﻿using Kimd.Common;
using Kimd.Logic;
using Kimd.Machine;
using Kimd.Motion;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using WorkStation.Common;

namespace WorkStation.Logic
{
    //前Arm模组 后Arm模组
    public class PutOKNGLogic : FlowBase
    {
        private bool _isFront;
        private Tray _bufferTray1;
        private Tray _bufferTray2;
        private Tray _aNGTray;
        private Tray _abNGTray;
        private Tray _abbNGTray;
        private Tray _spotCheckTray;
        private Axis _z1;
        private Axis _y1;
        private Axis _r1;
        private Axis _x1;
        private List<Cylinder> _recycleCylinders1;
        private List<Cylinder> _recycleVacs1;
        private List<Cylinder> _recycleRevVacs1;
        private List<Sensor> _recycleVacSenses1;

        private List<Cylinder> _feedCylinders1;
        private List<Cylinder> _feedVacs1;
        private List<Cylinder> _feedRevVacs1;

        private List<Cylinder> _bufferVacs1;
        private List<Sensor> _feedVacSenses1;

        private Axis _z2;
        private Axis _y2;
        private Axis _r2;
        private Axis _x2;
        private List<Cylinder> _recycleCylinders2;
        private List<Cylinder> _recycleVacs2;
        private List<Cylinder> _recycleRevVacs2;
        private List<Sensor> _recycleVacSenses2;

        private List<Cylinder> _feedCylinders2;
        private List<Cylinder> _feedVacs2;
        private List<Cylinder> _feedRevVacs2;

        private List<Cylinder> _bufferVacs2;
        private List<Sensor> _feedVacSenses2;

        //private List<Cylinder> _precisionUpFeedVacs1;
        //private List<Cylinder> _precisionDownFeedVacs1;
        //private List<Cylinder> _precisionUpFeedVacs2;
        //private List<Cylinder> _precisionDownFeedVacs2;

        //private List<Cylinder> _precisionUpRecycleVacs1;
        //private List<Cylinder> _precisionDownRecycleVacs1;
        //private List<Cylinder> _precisionUpRecycleVacs2;
        //private List<Cylinder> _precisionDownRecycleVacs2;


        //private Cylinder _upPositionCylinder1;
        //private Cylinder _upPositionCylinder2;
        //private Cylinder _downPositionCylinder1;
        //private Cylinder _downPositionCylinder2;

        private List<Cylinder> _upFeedPositionCylinder;
        private List<Cylinder> _downFeedPositionCylinder;
        private List<Cylinder> _upRecyclePositionCylinder;
        private List<Cylinder> _downRecyclePositionCylinder;



        private Axis _ngAxis;
        private Sensor _upInOrigin;
        private Sensor _ngInMove;
        private Sensor _downInOrigin;
        private Sensor _ngInOrigin;
        private Sensor _upInMove;
        private Sensor _downInMove;
        private bool[] grrLeftOrRight = new bool[3] { false, false, false };
        private bool[] startLeft = new bool[2] { false, false };
        public PutOKNGLogic(string flowName, FlowManager flowmanager, bool isFront)
            : base(flowName, flowmanager)
        {
            _isFront = isFront;
            if (_isFront)
            {
                _z1 = MachineResource.Instance.MachineAxis[$"Arm1Z轴"];
                _y1 = MachineResource.Instance.MachineAxis[$"Arm1Y轴"];
                _r1 = MachineResource.Instance.MachineAxis[$"Arm1U轴"];
                _x1 = MachineResource.Instance.MachineAxis[$"测试移载线1左轴"];
                this._recycleCylinders1 = new List<Cylinder>()
                {
                    MachineResource.Instance.MachineCylinder[$"Arm1上下气缸3"],
                    MachineResource.Instance.MachineCylinder[$"Arm1上下气缸4"],
                };
                this._recycleVacs1 = new List<Cylinder>()
                {
                    MachineResource.Instance.MachineCylinder[$"Arm1吸真空3"],
                    MachineResource.Instance.MachineCylinder[$"Arm1吸真空4"],
                };
                this._recycleRevVacs1 = new List<Cylinder>()
                {
                    MachineResource.Instance.MachineCylinder[$"Arm1破真空3"],
                    MachineResource.Instance.MachineCylinder[$"Arm1破真空4"],
                };
                this._recycleVacSenses1 = new List<Sensor>()
                {
                    MachineResource.Instance.MachineSensor[$"Arm1吸真空3达到"],
                    MachineResource.Instance.MachineSensor[$"Arm1吸真空4达到"],
                };
                this._feedCylinders1 = new List<Cylinder>()
                {
                    MachineResource.Instance.MachineCylinder[$"Arm1上下气缸1"],
                    MachineResource.Instance.MachineCylinder[$"Arm1上下气缸2"],
                };
                this._feedVacs1 = new List<Cylinder>()
                {
                    MachineResource.Instance.MachineCylinder[$"Arm1吸真空1"],
                    MachineResource.Instance.MachineCylinder[$"Arm1吸真空2"],
                };
                this._feedRevVacs1 = new List<Cylinder>()
                {
                    MachineResource.Instance.MachineCylinder[$"Arm1破真空1"],
                    MachineResource.Instance.MachineCylinder[$"Arm1破真空2"],
                };
                this._bufferVacs1 = new List<Cylinder>()
                {
                    MachineResource.Instance.MachineCylinder["精定位1OKBuffer位真空吸1"],
                    MachineResource.Instance.MachineCylinder["精定位1OKBuffer位真空吸2"],
                };
                this._feedVacSenses1 = new List<Sensor>()
                {
                    MachineResource.Instance.MachineSensor[$"Arm1吸真空1达到"],
                    MachineResource.Instance.MachineSensor[$"Arm1吸真空2达到"],
                };

                _z2 = MachineResource.Instance.MachineAxis[$"Arm2Z轴"];
                _y2 = MachineResource.Instance.MachineAxis[$"Arm2Y轴"];
                _r2 = MachineResource.Instance.MachineAxis[$"Arm2U轴"];
                _x2 = MachineResource.Instance.MachineAxis[$"测试移载线1右轴"];

                this._recycleCylinders2 = new List<Cylinder>()
                {
                    MachineResource.Instance.MachineCylinder[$"Arm2上下气缸3"],
                    MachineResource.Instance.MachineCylinder[$"Arm2上下气缸4"],
                };
                this._recycleVacs2 = new List<Cylinder>()
                {
                    MachineResource.Instance.MachineCylinder[$"Arm2吸真空3"],
                    MachineResource.Instance.MachineCylinder[$"Arm2吸真空4"],
                };
                this._recycleRevVacs2 = new List<Cylinder>()
                {
                    MachineResource.Instance.MachineCylinder[$"Arm2破真空3"],
                    MachineResource.Instance.MachineCylinder[$"Arm2破真空4"],
                };
                this._recycleVacSenses2 = new List<Sensor>()
                {
                    MachineResource.Instance.MachineSensor[$"Arm2吸真空3达到"],
                    MachineResource.Instance.MachineSensor[$"Arm2吸真空4达到"],
                };
                this._feedCylinders2 = new List<Cylinder>()
                {
                    MachineResource.Instance.MachineCylinder[$"Arm2上下气缸1"],
                    MachineResource.Instance.MachineCylinder[$"Arm2上下气缸2"],
                };
                this._feedVacs2 = new List<Cylinder>()
                {
                    MachineResource.Instance.MachineCylinder[$"Arm2吸真空1"],
                    MachineResource.Instance.MachineCylinder[$"Arm2吸真空2"],
                };
                this._feedRevVacs2 = new List<Cylinder>()
                {
                    MachineResource.Instance.MachineCylinder[$"Arm2破真空1"],
                    MachineResource.Instance.MachineCylinder[$"Arm2破真空2"],
                };
                this._bufferVacs2 = new List<Cylinder>()
                {
                    MachineResource.Instance.MachineCylinder["精定位1OKBuffer位真空吸3"],
                    MachineResource.Instance.MachineCylinder["精定位1OKBuffer位真空吸4"],
                };
                this._feedVacSenses2 = new List<Sensor>()
                {
                    MachineResource.Instance.MachineSensor[$"Arm2吸真空1达到"],
                    MachineResource.Instance.MachineSensor[$"Arm2吸真空2达到"],
                };

                //this._precisionUpFeedVacs1 = new List<Cylinder>()
                //{
                //    MachineResource.Instance.MachineCylinder["精定位1上层真空吸5"],
                //    MachineResource.Instance.MachineCylinder["精定位1上层真空吸6"],
                //};
                //this._precisionDownFeedVacs1 = new List<Cylinder>()
                //{
                //    MachineResource.Instance.MachineCylinder["精定位1下层真空吸5"],
                //    MachineResource.Instance.MachineCylinder["精定位1下层真空吸6"],
                //};
                //this._precisionUpRecycleVacs1 = new List<Cylinder>()
                //{
                //    MachineResource.Instance.MachineCylinder["精定位1上层真空吸7"],
                //    MachineResource.Instance.MachineCylinder["精定位1上层真空吸8"],
                //};
                //this._precisionDownRecycleVacs1 = new List<Cylinder>()
                //{
                //    MachineResource.Instance.MachineCylinder["精定位1下层真空吸7"],
                //    MachineResource.Instance.MachineCylinder["精定位1下层真空吸8"],
                //};
                //this._precisionUpFeedVacs2 = new List<Cylinder>()
                //{
                //    MachineResource.Instance.MachineCylinder["精定位1上层真空吸1"],
                //    MachineResource.Instance.MachineCylinder["精定位1上层真空吸2"],
                //};
                //this._precisionDownFeedVacs2 = new List<Cylinder>()
                //{
                //    MachineResource.Instance.MachineCylinder["精定位1下层真空吸1"],
                //    MachineResource.Instance.MachineCylinder["精定位1下层真空吸2"],
                //};
                //this._precisionUpRecycleVacs2 = new List<Cylinder>()
                //{
                //    MachineResource.Instance.MachineCylinder["精定位1上层真空吸3"],
                //    MachineResource.Instance.MachineCylinder["精定位1上层真空吸4"],
                //};
                //this._precisionDownRecycleVacs2 = new List<Cylinder>()
                //{
                //    MachineResource.Instance.MachineCylinder["精定位1下层真空吸3"],
                //    MachineResource.Instance.MachineCylinder["精定位1下层真空吸4"],
                //};

                this._upInOrigin = MachineResource.Instance.MachineSensor["精定位1上层移载气缸原点"];
                this._upInMove = MachineResource.Instance.MachineSensor["精定位1上层移载气缸动点"];
                this._downInOrigin = MachineResource.Instance.MachineSensor["精定位1下层移载气缸原点"];
                this._downInMove = MachineResource.Instance.MachineSensor["精定位1下层移载气缸动点"];
                this._ngInOrigin = MachineResource.Instance.MachineSensor["精定位1ANG盘在原点位"];
                this._ngInMove = MachineResource.Instance.MachineSensor["精定位1NG料移载气缸动点"];

                RegisterDirectSignal($"Arm1放料结束");
                RegisterDirectSignal($"Arm2放料结束");

                _bufferTray1 = new Tray(2, 1);
                _bufferTray1.Helper.NewEmptyTray();
                _bufferTray2 = new Tray(2, 1);
                _bufferTray2.Helper.NewEmptyTray();

                GlobalVariable.BufferTray1UIFront = new Tray(2, 1);
                GlobalVariable.BufferTray2UIFront = new Tray(2, 1);

                _ngAxis = MachineResource.Instance.MachineAxis["精定位1NG轴"];

                _upFeedPositionCylinder = new List<Cylinder>()
                {
                    MachineResource.Instance.MachineCylinder["精定位1上层定位气缸1-2"],
                    MachineResource.Instance.MachineCylinder["精定位1上层定位气缸2-2"]
                };

                _downFeedPositionCylinder = new List<Cylinder>()
                {
                    MachineResource.Instance.MachineCylinder["精定位1下层定位气缸1-2"],
                    MachineResource.Instance.MachineCylinder["精定位1下层定位气缸2-2"]
                };

                _upRecyclePositionCylinder = new List<Cylinder>()
                {
                    //arm2
                    MachineResource.Instance.MachineCylinder["精定位1上层定位气缸1"],
                    //arm1
                    MachineResource.Instance.MachineCylinder["精定位1上层定位气缸2"],
                };

                _downRecyclePositionCylinder = new List<Cylinder>()
                {
                    MachineResource.Instance.MachineCylinder["精定位1下层定位气缸1"],
                    MachineResource.Instance.MachineCylinder["精定位1下层定位气缸2"]
                };
            }
            else
            {
                _z1 = MachineResource.Instance.MachineAxis[$"Arm3Z轴"];
                _y1 = MachineResource.Instance.MachineAxis[$"Arm3Y轴"];
                _r1 = MachineResource.Instance.MachineAxis[$"Arm3U轴"];
                _x1 = MachineResource.Instance.MachineAxis[$"测试移载线2左轴"];
                this._recycleCylinders1 = new List<Cylinder>()
                {
                    MachineResource.Instance.MachineCylinder[$"Arm3上下气缸1"],
                    MachineResource.Instance.MachineCylinder[$"Arm3上下气缸2"],
                };
                this._recycleVacs1 = new List<Cylinder>()
                {
                    MachineResource.Instance.MachineCylinder[$"Arm3吸真空1"],
                    MachineResource.Instance.MachineCylinder[$"Arm3吸真空2"],
                };
                this._recycleRevVacs1 = new List<Cylinder>()
                {
                    MachineResource.Instance.MachineCylinder[$"Arm3破真空1"],
                    MachineResource.Instance.MachineCylinder[$"Arm3破真空2"],
                };
                this._recycleVacSenses1 = new List<Sensor>()
                {
                    MachineResource.Instance.MachineSensor[$"Arm3吸真空1达到"],
                    MachineResource.Instance.MachineSensor[$"Arm3吸真空2达到"],
                };
                this._feedCylinders1 = new List<Cylinder>()
                {
                    MachineResource.Instance.MachineCylinder[$"Arm3上下气缸3"],
                    MachineResource.Instance.MachineCylinder[$"Arm3上下气缸4"],
                };
                this._feedVacs1 = new List<Cylinder>()
                {
                    MachineResource.Instance.MachineCylinder[$"Arm3吸真空3"],
                    MachineResource.Instance.MachineCylinder[$"Arm3吸真空4"],
                };
                this._feedRevVacs1 = new List<Cylinder>()
                {
                    MachineResource.Instance.MachineCylinder[$"Arm3破真空3"],
                    MachineResource.Instance.MachineCylinder[$"Arm3破真空4"],
                };
                this._bufferVacs1 = new List<Cylinder>()
                {
                    MachineResource.Instance.MachineCylinder["精定位2OKBuffer位真空吸1"],
                    MachineResource.Instance.MachineCylinder["精定位2OKBuffer位真空吸2"],
                };
                this._feedVacSenses1 = new List<Sensor>()
                {
                    MachineResource.Instance.MachineSensor[$"Arm3吸真空3达到"],
                    MachineResource.Instance.MachineSensor[$"Arm3吸真空4达到"],
                };

                _z2 = MachineResource.Instance.MachineAxis[$"Arm4Z轴"];
                _y2 = MachineResource.Instance.MachineAxis[$"Arm4Y轴"];
                _r2 = MachineResource.Instance.MachineAxis[$"Arm4U轴"];
                _x2 = MachineResource.Instance.MachineAxis[$"测试移载线2右轴"];
                this._recycleCylinders2 = new List<Cylinder>()
                {
                    MachineResource.Instance.MachineCylinder[$"Arm4上下气缸3"],
                    MachineResource.Instance.MachineCylinder[$"Arm4上下气缸4"],
                };
                this._recycleVacs2 = new List<Cylinder>()
                {
                    MachineResource.Instance.MachineCylinder[$"Arm4吸真空3"],
                    MachineResource.Instance.MachineCylinder[$"Arm4吸真空4"],
                };
                this._recycleRevVacs2 = new List<Cylinder>()
                {
                    MachineResource.Instance.MachineCylinder[$"Arm4破真空3"],
                    MachineResource.Instance.MachineCylinder[$"Arm4破真空4"],
                };
                this._recycleVacSenses2 = new List<Sensor>()
                {
                    MachineResource.Instance.MachineSensor[$"Arm4吸真空3达到"],
                    MachineResource.Instance.MachineSensor[$"Arm4吸真空4达到"],
                };
                this._feedCylinders2 = new List<Cylinder>()
                {
                    MachineResource.Instance.MachineCylinder[$"Arm4上下气缸1"],
                    MachineResource.Instance.MachineCylinder[$"Arm4上下气缸2"],
                };
                this._feedVacs2 = new List<Cylinder>()
                {
                    MachineResource.Instance.MachineCylinder[$"Arm4吸真空1"],
                    MachineResource.Instance.MachineCylinder[$"Arm4吸真空2"],
                };
                this._feedRevVacs2 = new List<Cylinder>()
                {
                    MachineResource.Instance.MachineCylinder[$"Arm4破真空1"],
                    MachineResource.Instance.MachineCylinder[$"Arm4破真空2"],
                };
                this._bufferVacs2 = new List<Cylinder>()
                {
                    MachineResource.Instance.MachineCylinder["精定位2OKBuffer位真空吸3"],
                    MachineResource.Instance.MachineCylinder["精定位2OKBuffer位真空吸4"],
                };
                this._feedVacSenses2 = new List<Sensor>()
                {
                    MachineResource.Instance.MachineSensor[$"Arm4吸真空1达到"],
                    MachineResource.Instance.MachineSensor[$"Arm4吸真空2达到"],
                };
                //this._precisionUpFeedVacs1 = new List<Cylinder>()
                //{
                //    MachineResource.Instance.MachineCylinder["精定位2上层真空吸5"],
                //    MachineResource.Instance.MachineCylinder["精定位2上层真空吸6"],
                //};
                //this._precisionDownFeedVacs1 = new List<Cylinder>()
                //{
                //    MachineResource.Instance.MachineCylinder["精定位2下层真空吸5"],
                //    MachineResource.Instance.MachineCylinder["精定位2下层真空吸6"],
                //};
                //this._precisionUpFeedVacs2 = new List<Cylinder>()
                //{
                //    MachineResource.Instance.MachineCylinder["精定位2上层真空吸1"],
                //    MachineResource.Instance.MachineCylinder["精定位2上层真空吸2"],
                //};
                //this._precisionDownFeedVacs2 = new List<Cylinder>()
                //{
                //    MachineResource.Instance.MachineCylinder["精定位2下层真空吸1"],
                //    MachineResource.Instance.MachineCylinder["精定位2下层真空吸2"],
                //};
                //this._precisionUpRecycleVacs1 = new List<Cylinder>()
                //{
                //    MachineResource.Instance.MachineCylinder["精定位2上层真空吸7"],
                //    MachineResource.Instance.MachineCylinder["精定位2上层真空吸8"],
                //};
                //this._precisionDownRecycleVacs1 = new List<Cylinder>()
                //{
                //    MachineResource.Instance.MachineCylinder["精定位2下层真空吸7"],
                //    MachineResource.Instance.MachineCylinder["精定位2下层真空吸8"],
                //};
                //this._precisionUpRecycleVacs2 = new List<Cylinder>()
                //{
                //    MachineResource.Instance.MachineCylinder["精定位2上层真空吸3"],
                //    MachineResource.Instance.MachineCylinder["精定位2上层真空吸4"],
                //};
                //this._precisionDownRecycleVacs2 = new List<Cylinder>()
                //{
                //    MachineResource.Instance.MachineCylinder["精定位2下层真空吸3"],
                //    MachineResource.Instance.MachineCylinder["精定位2下层真空吸4"],
                //};

                this._upInOrigin = MachineResource.Instance.MachineSensor["精定位2上层移载气缸原点"];
                this._upInMove = MachineResource.Instance.MachineSensor["精定位2上层移载气缸动点"];
                this._downInOrigin = MachineResource.Instance.MachineSensor["精定位2下层移载气缸原点"];
                this._downInMove = MachineResource.Instance.MachineSensor["精定位2下层移载气缸动点"];
                this._ngInOrigin = MachineResource.Instance.MachineSensor["精定位2ANG盘在原点位"];
                this._ngInMove = MachineResource.Instance.MachineSensor["精定位2NG料移载气缸动点"];

                RegisterDirectSignal($"Arm3放料结束");
                RegisterDirectSignal($"Arm4放料结束");

                _bufferTray1 = new Tray(2, 1);
                _bufferTray1.Helper.NewEmptyTray();
                _bufferTray2 = new Tray(2, 1);
                _bufferTray2.Helper.NewEmptyTray();

                GlobalVariable.BufferTray1UIBack = new Tray(2, 1);
                GlobalVariable.BufferTray2UIBack = new Tray(2, 1);

                _ngAxis = MachineResource.Instance.MachineAxis["精定位2NG轴"];

                _upFeedPositionCylinder = new List<Cylinder>()
                {
                    MachineResource.Instance.MachineCylinder["精定位2上层定位气缸1-2"],
                    MachineResource.Instance.MachineCylinder["精定位2上层定位气缸2-2"]
                };

                _downFeedPositionCylinder = new List<Cylinder>()
                {
                    MachineResource.Instance.MachineCylinder["精定位2下层定位气缸1-2"],
                    MachineResource.Instance.MachineCylinder["精定位2下层定位气缸2-2"]
                };

                _upRecyclePositionCylinder = new List<Cylinder>()
                {
                    MachineResource.Instance.MachineCylinder["精定位2上层定位气缸1"],
                    //arm3
                    MachineResource.Instance.MachineCylinder["精定位2上层定位气缸2"]
                };

                _downRecyclePositionCylinder = new List<Cylinder>()
                {
                    MachineResource.Instance.MachineCylinder["精定位2下层定位气缸1"],
                    MachineResource.Instance.MachineCylinder["精定位2下层定位气缸2"]
                };
            }

            _aNGTray = new Tray(2, 12);
            _aNGTray.Direction = TrayDir.YZ;
            _abNGTray = new Tray(2, 12);
            _abNGTray.Direction = TrayDir.YZ;
            _abbNGTray = new Tray(2, 12);
            _spotCheckTray = new Tray(1, 4);

        }
        public override void Calibrate()
        {
            base.Calibrate();
        }
        public override void Home()
        {
            _aNGTray.Helper.NewEmptyTray();
            _abNGTray.Helper.NewEmptyTray();
            _abbNGTray.Helper.NewEmptyTray();

            _bufferTray1.Helper.NewEmptyTray();
            _bufferTray2.Helper.NewEmptyTray();

            if (_isFront)
            {
                GlobalVariable.BufferTray1UIFront.Helper.NewEmptyTray();
                GlobalVariable.BufferTray2UIFront.Helper.NewEmptyTray();
            }
            else
            {
                GlobalVariable.BufferTray1UIBack.Helper.NewEmptyTray();
                GlobalVariable.BufferTray2UIBack.Helper.NewEmptyTray();
            }
            GlobalVariable.CosmeticFinishTesterIndex = new List<int>();
            startLeft = new bool[2] { false, false };
        }
        public override void InSingleRunMode()
        {
            if (GlobalVariable.OnSingleRunPause != null)
                GlobalVariable.OnSingleRunPause();
        }
        public override void Init(out string errInfo)
        {
            base.Init(out errInfo);
        }
        public override void Method()
        {
            if (!CheckFlowCondition()) return;

            if (GlobalVariable.IsSpotChecking)
            {
                SpotCheck2();
            }
            else
            {

                Tray recycleTray1 = null;
                Tray recycleTray2 = null;
                Tray feedTray1 = null;
                Tray feedTray2 = null;

                if (_isFront)
                {
                    WaitForSignal("Arm1模组", "Arm1准备放完成料");
                    if (!CheckFlowCondition()) return;
                    WaitForSignal("Arm2模组", "Arm2准备放完成料");
                    if (!CheckFlowCondition()) return;
                    recycleTray1 = (_flowManager.SelectFlow("Arm1模组") as TransferLogic).GetRecycleTray();
                    recycleTray2 = (_flowManager.SelectFlow("Arm2模组") as TransferLogic).GetRecycleTray();
                    feedTray1 = (_flowManager.SelectFlow("Arm1模组") as TransferLogic).GetFeedTray();
                    feedTray2 = (_flowManager.SelectFlow("Arm2模组") as TransferLogic).GetFeedTray();
                    #region 进行禁用治具跑料处理
                    if (feedTray1.Helper.Any(o => o.Status == CellStatus.HasProduct) || feedTray2.Helper.Any(o => o.Status == CellStatus.HasProduct))
                    {
                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"当前存在治具禁用，会将产品进行抛NG区", this.Description, 0, ""));
                        bool putNg1 = feedTray1.Helper.Any(o => o.Status == CellStatus.HasProduct);
                        bool putNg2 = feedTray2.Helper.Any(o => o.Status == CellStatus.HasProduct);
                        if (feedTray1.Helper.GetCell(0).Status == CellStatus.HasProduct)
                        {
                            string barcode = feedTray1.Helper.GetCell(0).SN;
                            feedTray1.Helper.SetCellBarcode(0, "NG");
                            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"feedTray1:{barcode}变为NG", this.Description, 0, ""));
                        }
                        if (feedTray1.Helper.GetCell(1).Status == CellStatus.HasProduct)
                        {
                            string barcode = feedTray1.Helper.GetCell(1).SN;
                            feedTray1.Helper.SetCellBarcode(1, "NG");
                            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"feedTray1:{barcode}变为NG", this.Description, 0, ""));
                        }
                        if (feedTray2.Helper.GetCell(0).Status == CellStatus.HasProduct)
                        {
                            string barcode = feedTray2.Helper.GetCell(0).SN;
                            feedTray2.Helper.SetCellBarcode(0, "NG");
                            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"feedTray2:{barcode}变为NG", this.Description, 0, ""));
                        }
                        if (feedTray2.Helper.GetCell(1).Status == CellStatus.HasProduct)
                        {
                            string barcode = feedTray2.Helper.GetCell(1).SN;
                            feedTray2.Helper.SetCellBarcode(1, "NG");
                            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"feedTray2:{barcode}变为NG", this.Description, 0, ""));
                        }
                        if (!CheckFlowCondition()) return;
                        (_flowManager.SelectFlow("前放扫码NG模组") as PutScanNGLogic).PutScanP(feedTray1, feedTray2);
                        if (!CheckFlowCondition()) return;
                        if (putNg2)
                            SingleAxisMove2Point(_x2, "Arm右避让位");
                        else if (putNg1)
                            SingleAxisMove2Point(_x1, "Arm左避让位");
                        if (!CheckFlowCondition()) return;
                    }
                    #endregion
                }
                else
                {
                    WaitForSignal("Arm3模组", "Arm3准备放完成料");
                    if (!CheckFlowCondition()) return;
                    WaitForSignal("Arm4模组", "Arm4准备放完成料");
                    if (!CheckFlowCondition()) return;
                    recycleTray1 = (_flowManager.SelectFlow("Arm3模组") as TransferLogic).GetRecycleTray();
                    recycleTray2 = (_flowManager.SelectFlow("Arm4模组") as TransferLogic).GetRecycleTray();
                    feedTray1 = (_flowManager.SelectFlow("Arm3模组") as TransferLogic).GetFeedTray();
                    feedTray2 = (_flowManager.SelectFlow("Arm4模组") as TransferLogic).GetFeedTray();
                    #region 进行禁用治具跑料处理
                    if (feedTray1.Helper.Any(o => o.Status == CellStatus.HasProduct) || feedTray2.Helper.Any(o => o.Status == CellStatus.HasProduct))
                    {
                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"当前存在治具禁用，会将产品进行抛NG区", this.Description, 0, ""));
                        bool putNg1 = feedTray1.Helper.Any(o => o.Status == CellStatus.HasProduct);
                        bool putNg2 = feedTray2.Helper.Any(o => o.Status == CellStatus.HasProduct);
                        if (feedTray1.Helper.GetCell(0).Status == CellStatus.HasProduct)
                        {
                            string barcode = feedTray1.Helper.GetCell(0).SN;
                            feedTray1.Helper.SetCellBarcode(0, "NG");
                            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"feedTray1:{barcode}变为NG", this.Description, 0, ""));
                        }
                        if (feedTray1.Helper.GetCell(1).Status == CellStatus.HasProduct)
                        {
                            string barcode = feedTray1.Helper.GetCell(1).SN;
                            feedTray1.Helper.SetCellBarcode(1, "NG");
                            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"feedTray1:{barcode}变为NG", this.Description, 0, ""));
                        }
                        if (feedTray2.Helper.GetCell(0).Status == CellStatus.HasProduct)
                        {
                            string barcode = feedTray2.Helper.GetCell(0).SN;
                            feedTray2.Helper.SetCellBarcode(0, "NG");
                            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"feedTray2:{barcode}变为NG", this.Description, 0, ""));
                        }
                        if (feedTray2.Helper.GetCell(1).Status == CellStatus.HasProduct)
                        {
                            string barcode = feedTray2.Helper.GetCell(1).SN;
                            feedTray2.Helper.SetCellBarcode(1, "NG");
                            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"feedTray2:{barcode}变为NG", this.Description, 0, ""));
                        }
                        if (!CheckFlowCondition()) return;
                        (_flowManager.SelectFlow("后放扫码NG模组") as PutScanNGLogic).PutScanP(feedTray1, feedTray2);
                        if (!CheckFlowCondition()) return;
                        if (putNg2)
                            SingleAxisMove2Point(_x2, "Arm右避让位");
                        else if (putNg1)
                            SingleAxisMove2Point(_x1, "Arm左避让位");
                        if (!CheckFlowCondition()) return;
                    }
                    #endregion
                }
                //检查是否有NG
                //如果1头有NG
                if (!GlobalVariable.IsOnlineRetest)
                {
                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"当前非复测模式", this.Description, 0, ""));
                    if (recycleTray1.Helper.Any(c => c.Status == CellStatus.HasProduct && (c.Result == TestResult.FirstTimeNG || c.Result == TestResult.SecondTimeNG)))
                    {
                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"arm recycle1有NG料", this.Description, 0, ""));
                        checkTrayFullAndReplace(_abbNGTray, "NG Tray满料！请取走，并放置空Tray!", _isFront ? "静定位1模组" : "精定位2模组", GlobalVariable.IsDryRun);
                        int index = 0;
                        foreach (var cell in recycleTray1.Helper)
                        {
                            if (cell.Status == CellStatus.HasProduct &&
                               (cell.Result == TestResult.FirstTimeNG || cell.Result == TestResult.SecondTimeNG))
                            {
                                LogHelper.Instance.Log(this.Description, "放NG开始", MessageLevel.CT);
                                //可能电缸要动到某个位置
                                putABBNG(_abbNGTray, 0, $"吸嘴{3 + index}", index, recycleTray1);
                                //putNG(_abbNGTray, "ABBNG矩阵Arm左", "Arm右避让位", 0, $"吸嘴{3 + index}", index, recycleTray1);
                                LogHelper.Instance.Log(this.Description, "放NG结束", MessageLevel.CT);
                                if (!CheckFlowCondition()) return;
                                checkTrayFullAndReplace(_abbNGTray, "NG Tray满料！请取走，并放置空Tray!", _isFront ? "静定位1模组" : "精定位2模组", GlobalVariable.IsDryRun);
                            }
                            index++;
                        }
                    }
                    //如果2头有NG
                    if (recycleTray2.Helper.Any(c => c.Status == CellStatus.HasProduct && (c.Result == TestResult.FirstTimeNG || c.Result == TestResult.SecondTimeNG)))
                    {
                        if (!CheckFlowCondition()) return;
                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"arm recycle2有NG料", this.Description, 0, ""));
                        checkTrayFullAndReplace(_abbNGTray, "NG Tray满料！请取走，并放置空Tray!", _isFront ? "静定位1模组" : "精定位2模组", GlobalVariable.IsDryRun);
                        int index = 0;
                        foreach (var cell in recycleTray2.Helper)
                        {
                            if (cell.Status == CellStatus.HasProduct &&
                                (cell.Result == TestResult.FirstTimeNG || cell.Result == TestResult.SecondTimeNG))
                            {
                                LogHelper.Instance.Log(this.Description, "放NG开始", MessageLevel.CT);
                                //可能电缸要动到某个位置
                                putABBNG(_abbNGTray, 1, $"吸嘴{3 + index}", index, recycleTray2);
                                //putNG(_aNGTray, "ANG矩阵Arm右", "Arm左避让位", 1, $"吸嘴{3 + index}", index, recycleTray2);
                                LogHelper.Instance.Log(this.Description, "放NG结束", MessageLevel.CT);
                                if (!CheckFlowCondition()) return;
                                checkTrayFullAndReplace(_abbNGTray, "NG Tray满料！请取走，并放置空Tray!", _isFront ? "静定位1模组" : "精定位2模组", GlobalVariable.IsDryRun);
                            }
                            index++;
                        }
                    }

                    SingleAxisMove2Point(_ngAxis, "安全位");
                    if (!CheckFlowCondition()) return;
                }
                else
                {
                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"当前复测模式", this.Description, 0, ""));
                    //ANG
                    if (recycleTray1.Helper.Any(c => c.Status == CellStatus.HasProduct && c.Result == TestResult.FirstTimeNG))
                    {
                        if (!CheckFlowCondition()) return;
                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"arm recycle1有 A NG料", this.Description, 0, ""));
                        int index = 0;
                        foreach (var cell in recycleTray1.Helper)
                        {
                            if (cell.Status == CellStatus.HasProduct &&
                                cell.Result == TestResult.FirstTimeNG)
                            {
                                LogHelper.Instance.Log(this.Description, "放ANG开始", MessageLevel.CT);
                                putANG(_aNGTray, "ANG矩阵Arm左", "Arm右避让位", 0, $"吸嘴{3 + index}", index, recycleTray1.Helper.GetCell(index).TestedTesters.Last(), recycleTray1);
                                LogHelper.Instance.Log(this.Description, "放ANG结束", MessageLevel.CT);
                                if (!CheckFlowCondition()) return;
                            }
                            index++;
                        }
                    }
                    //ABNG
                    if (recycleTray1.Helper.Any(c => c.Status == CellStatus.HasProduct && c.Result == TestResult.SecondTimeNG))
                    {
                        if (!CheckFlowCondition()) return;
                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"arm recycle1有 AB NG料", this.Description, 0, ""));
                        int index = 0;
                        foreach (var cell in recycleTray1.Helper)
                        {
                            if (cell.Status == CellStatus.HasProduct &&
                                cell.Result == TestResult.SecondTimeNG)
                            {
                                LogHelper.Instance.Log(this.Description, "放ABNG开始", MessageLevel.CT);
                                putABNG(_abNGTray, "ABNG矩阵Arm左", "Arm右避让位", 0, $"吸嘴{3 + index}", index, recycleTray1.Helper.GetCell(index).TestedTesters.Last(), recycleTray1);
                                LogHelper.Instance.Log(this.Description, "放ABNG结束", MessageLevel.CT);
                                if (!CheckFlowCondition()) return;
                            }
                            index++;
                        }
                    }
                    //ABBNG
                    if (recycleTray1.Helper.Any(c => c.Status == CellStatus.HasProduct && c.Result == TestResult.ThirdTimeNG))
                    {
                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"arm recycle1有 ABB NG料", this.Description, 0, ""));
                        checkTrayFullAndReplace(_abbNGTray, "ABB NG Tray满料！请取走，并放置空Tray!", _isFront ? "静定位1模组" : "精定位2模组", GlobalVariable.IsDryRun);
                        int index = 0;
                        foreach (var cell in recycleTray1.Helper)
                        {
                            if (cell.Status == CellStatus.HasProduct &&
                                cell.Result == TestResult.ThirdTimeNG)
                            {
                                LogHelper.Instance.Log(this.Description, "放ABBNG开始", MessageLevel.CT);
                                putABBNG(_abbNGTray, 0, $"吸嘴{3 + index}", index, recycleTray1);
                                LogHelper.Instance.Log(this.Description, "放ABBNG结束", MessageLevel.CT);
                                if (!CheckFlowCondition()) return;
                                checkTrayFullAndReplace(_abbNGTray, "ABB NG Tray满料！请取走，并放置空Tray!", _isFront ? "静定位1模组" : "精定位2模组", GlobalVariable.IsDryRun);
                            }
                            index++;
                        }
                    }
                    //如果2头有NG
                    if (recycleTray2.Helper.Any(c => c.Status == CellStatus.HasProduct && c.Result == TestResult.FirstTimeNG))
                    {
                        if (!CheckFlowCondition()) return;
                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"arm recycle2有 A NG料", this.Description, 0, ""));
                        int index = 0;
                        foreach (var cell in recycleTray2.Helper)
                        {
                            if (cell.Status == CellStatus.HasProduct &&
                                cell.Result == TestResult.FirstTimeNG)
                            {
                                LogHelper.Instance.Log(this.Description, "放ANG开始", MessageLevel.CT);
                                putANG(_aNGTray, "ANG矩阵Arm右", "Arm左避让位", 1, $"吸嘴{3 + index}", index, recycleTray2.Helper.GetCell(index).TestedTesters.Last(), recycleTray2);
                                LogHelper.Instance.Log(this.Description, "放ANG结束", MessageLevel.CT);
                                if (!CheckFlowCondition()) return;
                            }
                            index++;
                        }
                    }
                    //ABNG
                    if (recycleTray2.Helper.Any(c => c.Status == CellStatus.HasProduct && c.Result == TestResult.SecondTimeNG))
                    {
                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"arm recycle2有 AB NG料", this.Description, 0, ""));
                        int index = 0;
                        foreach (var cell in recycleTray2.Helper)
                        {
                            if (cell.Status == CellStatus.HasProduct &&
                                cell.Result == TestResult.SecondTimeNG)
                            {
                                LogHelper.Instance.Log(this.Description, "放ABNG开始", MessageLevel.CT);
                                putABNG(_abNGTray, "ABNG矩阵Arm右", "Arm左避让位", 1, $"吸嘴{3 + index}", index, recycleTray2.Helper.GetCell(index).TestedTesters.Last(), recycleTray2);
                                LogHelper.Instance.Log(this.Description, "放ABNG结束", MessageLevel.CT);
                                if (!CheckFlowCondition()) return;
                            }
                            index++;
                        }
                    }
                    //ABBNG
                    if (recycleTray2.Helper.Any(c => c.Status == CellStatus.HasProduct && c.Result == TestResult.ThirdTimeNG))
                    {
                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"arm recycle2有 ABB NG料", this.Description, 0, ""));
                        checkTrayFullAndReplace(_abbNGTray, "ABB NG Tray满料！请取走，并放置空Tray!", _isFront ? "静定位1模组" : "精定位2模组", GlobalVariable.IsDryRun);
                        int index = 0;
                        foreach (var cell in recycleTray2.Helper)
                        {
                            if (cell.Status == CellStatus.HasProduct &&
                                cell.Result == TestResult.ThirdTimeNG)
                            {
                                LogHelper.Instance.Log(this.Description, "放ABBNG开始", MessageLevel.CT);
                                putABBNG(_abbNGTray, 1, $"吸嘴{3 + index}", index, recycleTray2);
                                LogHelper.Instance.Log(this.Description, "放ABBNG结束", MessageLevel.CT);
                                if (!CheckFlowCondition()) return;
                                checkTrayFullAndReplace(_abbNGTray, "ABB NG Tray满料！请取走，并放置空Tray!", _isFront ? "静定位1模组" : "精定位2模组", GlobalVariable.IsDryRun);
                            }
                            index++;
                        }
                    }
                }

                //取复测料
                if (GlobalVariable.IsOnlineRetest)
                {
                    int id = _isFront ? 0 : 2;
                    if (GlobalVariable.ClearNG[id])
                    {
                        GlobalVariable.ClearNG[id] = false;
                        GlobalVariable.ClearNG[id + 1] = false;

                        //如果左侧有可以做ABNG的料
                        if (LeftHasEnoughABNG2Retest(true, out (int, int) abngcellindex))
                        {
                            //先把AB NG的料取到手
                            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"Arm左 AB NG料 够复测", this.Description, 0, ""));

                            //先取左侧的AB NG  AB 的index 是 cell的序号
                            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"取ABNG料", this.Description, 0, ""));
                            getABNG(_abNGTray, "ABNG矩阵Arm左", "Arm右避让位", 0, $"吸嘴{1 + 0}", 0, abngcellindex.Item1, feedTray1);
                            if (!CheckFlowCondition()) return;

                            //左边有AB NG 且取完了  看看右边有没有
                            if (RightHasEnoughABNG2Retest(false, out (int, int) abngcellindexRight))
                            {
                                MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"取ABNG料", this.Description, 0, ""));
                                getABNG(_abNGTray, "ABNG矩阵Arm右", "Arm左避让位", 1, $"吸嘴{1 + 0}", 0, abngcellindexRight.Item1, feedTray2);
                                if (!CheckFlowCondition()) return;
                            }
                            //左边有AB NG 但右边 没有 AB NG，则看看 左边 有没有 ANG 然后用右侧 ARM取
                            else
                            {
                                if (LeftHasEnoughANG2Retest(true, out (int, int) angtesterindex2))
                                {
                                    //A NG 的 index是 tester的index
                                    if (angtesterindex2.Item1 != -1)
                                    {
                                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"右边手没有AB NG需要复测，但是有A NG需要复测,有两个", this.Description, 0, ""));
                                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"取ANG料", this.Description, 0, ""));
                                        getANG(_aNGTray, "ANG矩阵Arm右", "Arm左避让位", 1, $"吸嘴{1 + 0}", 0, angtesterindex2.Item1, feedTray2);
                                        if (!CheckFlowCondition()) return;
                                    }
                                }
                            }
                        }
                        else if (RightHasEnoughABNG2Retest(true, out (int, int) abngtesterindexRight))
                        {
                            //先把AB NG的料取到手
                            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"Arm右 AB NG料 够复测", this.Description, 0, ""));

                            //先取右侧的AB NG
                            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"取ABNG料", this.Description, 0, ""));
                            getABNG(_abNGTray, "ABNG矩阵Arm右", "Arm左避让位", 1, $"吸嘴{1 + 0}", 0, abngtesterindexRight.Item1, feedTray2);
                            if (!CheckFlowCondition()) return;

                            //此时可以确认左侧没有AB NG，不然不会进这个if 直接看 右侧有没有  ANG  让左侧 ARM 取
                            if (RightHasEnoughANG2Retest(false, out (int, int) angtesterindex))
                            {
                                if (angtesterindex.Item1 != -1)
                                {
                                    //是分布在2个穴位的ANG
                                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"左边手没有AB NG需要复测，但是有A NG需要复测， 有两个", this.Description, 0, ""));
                                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"取ANG料", this.Description, 0, ""));
                                    getANG(_aNGTray, "ANG矩阵Arm左", "Arm右避让位", 0, $"吸嘴{1 + 0}", 0, angtesterindex.Item1, feedTray1);
                                    if (!CheckFlowCondition()) return;
                                }
                            }
                        }
                        else
                        {
                            //先看右边，用左Arm去取456的A NG
                            if (RightHasEnoughANG2Retest(true, out (int, int) angtesterindex))
                            {
                                if (angtesterindex.Item1 != -1)
                                {
                                    //是分布在2个穴位的ANG
                                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"左边手没有AB NG需要复测，但是有A NG需要复测， 有两个", this.Description, 0, ""));
                                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"取ANG料", this.Description, 0, ""));
                                    getANG(_aNGTray, "ANG矩阵Arm左", "Arm右避让位", 0, $"吸嘴{1 + 0}", 0, angtesterindex.Item1, feedTray1);
                                    if (!CheckFlowCondition()) return;
                                }
                            }
                            if (LeftHasEnoughANG2Retest(true, out (int, int) angtesterindex2))
                            {
                                if (angtesterindex2.Item1 != -1)
                                {
                                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"右边手没有AB NG需要复测，但是有A NG需要复测,有两个", this.Description, 0, ""));
                                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"取ANG料", this.Description, 0, ""));
                                    getANG(_aNGTray, "ANG矩阵Arm右", "Arm左避让位", 1, $"吸嘴{1 + 0}", 0, angtesterindex2.Item1, feedTray2);
                                    if (!CheckFlowCondition()) return;
                                }
                            }
                        }
                        //TODO 清料情况下，判定做A AB的逻辑不同
                        //之前的不该删除，需要添加
                    }
                    else
                    {
                        //如果左侧有可以做ABNG的料
                        if (LeftHasEnoughABNG2Retest(false, out (int, int) abngcellindex))
                        {
                            //先把AB NG的料取到手
                            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"Arm左 AB NG料 够复测", this.Description, 0, ""));

                            //先取左侧的AB NG  AB 的index 是 cell的序号
                            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"取ABNG料", this.Description, 0, ""));
                            getABNG(_abNGTray, "ABNG矩阵Arm左", "Arm右避让位", 0, $"吸嘴{1 + 0}", 0, abngcellindex.Item1, feedTray1);
                            if (!CheckFlowCondition()) return;
                            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"取ABNG料", this.Description, 0, ""));
                            getABNG(_abNGTray, "ABNG矩阵Arm左", "Arm右避让位", 0, $"吸嘴{1 + 1}", 1, abngcellindex.Item2, feedTray1);
                            if (!CheckFlowCondition()) return;

                            //左边有AB NG 且取完了  看看右边有没有
                            if (RightHasEnoughABNG2Retest(false, out (int, int) abngcellindexRight))
                            {
                                MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"取ABNG料", this.Description, 0, ""));
                                getABNG(_abNGTray, "ABNG矩阵Arm右", "Arm左避让位", 1, $"吸嘴{1 + 0}", 0, abngcellindexRight.Item1, feedTray2);
                                if (!CheckFlowCondition()) return;
                                MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"取ABNG料", this.Description, 0, ""));
                                getABNG(_abNGTray, "ABNG矩阵Arm右", "Arm左避让位", 1, $"吸嘴{1 + 1}", 1, abngcellindexRight.Item2, feedTray2);
                                if (!CheckFlowCondition()) return;
                            }
                            //左边有AB NG 但右边 没有 AB NG，则看看 左边 有没有 ANG 然后用右侧 ARM取
                            else
                            {
                                if (LeftHasEnoughANG2Retest(false, out (int, int) angtesterindex2))
                                {
                                    //A NG 的 index是 tester的index
                                    if (angtesterindex2.Item1 != -1)
                                    {
                                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"右边手没有AB NG需要复测，但是有A NG需要复测,有两个", this.Description, 0, ""));
                                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"取ANG料", this.Description, 0, ""));
                                        getANG(_aNGTray, "ANG矩阵Arm右", "Arm左避让位", 1, $"吸嘴{1 + 0}", 0, angtesterindex2.Item1, feedTray2);
                                        if (!CheckFlowCondition()) return;
                                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"取ANG料", this.Description, 0, ""));
                                        getANG(_aNGTray, "ANG矩阵Arm右", "Arm左避让位", 1, $"吸嘴{1 + 1}", 1, angtesterindex2.Item2, feedTray2);
                                        if (!CheckFlowCondition()) return;
                                    }
                                }
                            }
                        }
                        else if (RightHasEnoughABNG2Retest(false, out (int, int) abngtesterindexRight))
                        {
                            //先把AB NG的料取到手
                            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"Arm右 AB NG料 够复测", this.Description, 0, ""));

                            //先取右侧的AB NG
                            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"取ABNG料", this.Description, 0, ""));
                            getABNG(_abNGTray, "ABNG矩阵Arm右", "Arm左避让位", 1, $"吸嘴{1 + 0}", 0, abngtesterindexRight.Item1, feedTray2);
                            if (!CheckFlowCondition()) return;
                            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"取ABNG料", this.Description, 0, ""));
                            getABNG(_abNGTray, "ABNG矩阵Arm右", "Arm左避让位", 1, $"吸嘴{1 + 1}", 1, abngtesterindexRight.Item2, feedTray2);
                            if (!CheckFlowCondition()) return;

                            //此时可以确认左侧没有AB NG，不然不会进这个if 直接看 右侧有没有  ANG  让左侧 ARM 取
                            if (RightHasEnoughANG2Retest(false, out (int, int) angtesterindex))
                            {
                                if (angtesterindex.Item1 != -1)
                                {
                                    //是分布在2个穴位的ANG
                                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"左边手没有AB NG需要复测，但是有A NG需要复测， 有两个", this.Description, 0, ""));
                                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"取ANG料", this.Description, 0, ""));
                                    getANG(_aNGTray, "ANG矩阵Arm左", "Arm右避让位", 0, $"吸嘴{1 + 0}", 0, angtesterindex.Item1, feedTray1);
                                    if (!CheckFlowCondition()) return;
                                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"取ANG料", this.Description, 0, ""));
                                    getANG(_aNGTray, "ANG矩阵Arm左", "Arm右避让位", 0, $"吸嘴{1 + 1}", 1, angtesterindex.Item2, feedTray1);
                                    if (!CheckFlowCondition()) return;
                                }
                            }
                        }
                        else
                        {
                            //先看右边，用左Arm去取456的A NG
                            if (RightHasEnoughANG2Retest(false, out (int, int) angtesterindex))
                            {
                                if (angtesterindex.Item1 != -1)
                                {
                                    //是分布在2个穴位的ANG
                                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"左边手没有AB NG需要复测，但是有A NG需要复测， 有两个", this.Description, 0, ""));
                                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"取ANG料", this.Description, 0, ""));
                                    getANG(_aNGTray, "ANG矩阵Arm左", "Arm右避让位", 0, $"吸嘴{1 + 0}", 0, angtesterindex.Item1, feedTray1);
                                    if (!CheckFlowCondition()) return;
                                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"取ANG料", this.Description, 0, ""));
                                    getANG(_aNGTray, "ANG矩阵Arm左", "Arm右避让位", 0, $"吸嘴{1 + 1}", 1, angtesterindex.Item2, feedTray1);
                                    if (!CheckFlowCondition()) return;
                                }
                            }
                            if (LeftHasEnoughANG2Retest(false, out (int, int) angtesterindex2))
                            {
                                if (angtesterindex2.Item1 != -1)
                                {
                                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"右边手没有AB NG需要复测，但是有A NG需要复测,有两个", this.Description, 0, ""));
                                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"取ANG料", this.Description, 0, ""));
                                    getANG(_aNGTray, "ANG矩阵Arm右", "Arm左避让位", 1, $"吸嘴{1 + 0}", 0, angtesterindex2.Item1, feedTray2);
                                    if (!CheckFlowCondition()) return;
                                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"取ANG料", this.Description, 0, ""));
                                    getANG(_aNGTray, "ANG矩阵Arm右", "Arm左避让位", 1, $"吸嘴{1 + 1}", 1, angtesterindex2.Item2, feedTray2);
                                    if (!CheckFlowCondition()) return;
                                }
                            }
                        }
                    }

                    //不管是ANG还是ABNG，只要手上有料要复测，就要借助精定位重定位一下
                    if ((feedTray1.Helper.Any(c => c.Status == CellStatus.HasProduct)) ||
                        (feedTray2.Helper.Any(c => c.Status == CellStatus.HasProduct)))
                    {
                        SingleAxisMove2Point(_ngAxis, "安全位");
                        if (!CheckFlowCondition()) return;
                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"手上有待复测的料", this.Description, 0, ""));
                        //这时候就要等精定位到位的信号了，否则无法借助精定位
                        bool upReady = false;
                        if (_isFront)
                        {
                            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"复测模式下等静定位过来，因为要借助精定位重新定位复测料", this.Description, 0, ""));
                            //接管了arm模组
                            while ((!CheckSignal("精定位移载1", $"Arm1精定位到位") ||
                                    !CheckSignal("精定位移载1", $"Arm2精定位到位")) &&
                                    !IsBreak())
                            {
                                Thread.Sleep(20);
                            }
                            upReady = (_flowManager.SelectFlow("精定位移载1") as PrecisionLogic).GetTwoLayerInPositionStatus();
                            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"当前上下层状态：{upReady}", this.Description, 0, ""));
                        }
                        else
                        {
                            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"复测模式下等静定位过来，因为要借助精定位重新定位复测料", this.Description, 0, ""));
                            //接管了arm模组
                            while ((!CheckSignal("精定位移载2", $"Arm3精定位到位") ||
                                    !CheckSignal("精定位移载2", $"Arm4精定位到位")) &&
                                    !IsBreak())
                            {
                                Thread.Sleep(20);
                            }
                            upReady = (_flowManager.SelectFlow("精定位移载2") as PrecisionLogic).GetTwoLayerInPositionStatus();
                            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"当前上下层状态：{upReady}", this.Description, 0, ""));
                        }
                        //检查两个喂料手，如果有料，放到OK位置去精定位一下，再取起来
                        //if (feedTray1.Helper.Any(c => c.Status == CellStatus.HasProduct))
                        //{
                        //    //气缸回去
                        //    SingleAxisMove2Point(_ngAxis, "安全位");
                        //    if (!CheckFlowCondition()) return;
                        //    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"放手上的料到精定位重定位一下", this.Description, 0, ""));
                        //    useOK2Position(upReady, 0);
                        //    if (!CheckFlowCondition()) return;
                        //}
                        //if (feedTray2.Helper.Any(c => c.Status == CellStatus.HasProduct))
                        //{
                        //    //气缸回去
                        //    SingleAxisMove2Point(_ngAxis, "安全位");
                        //    if (!CheckFlowCondition()) return;
                        //    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"放手上的料到精定位重定位一下", this.Description, 0, ""));
                        //    useOK2Position(upReady, 1);
                        //    if (!CheckFlowCondition()) return;
                        //}
                        //先做左边的重复测试，不调换穴位，不调换治具
                        bool use11 = feedTray1.Helper.Any(c => c.Status == CellStatus.HasProduct);
                        bool use22 = feedTray2.Helper.Any(c => c.Status == CellStatus.HasProduct);
                        PutOK2(upReady,
                               feedTray1,
                               feedTray2,
                               use11,
                               use22);
                        if (!CheckFlowCondition()) return;
                        DoPosition2(upReady);
                        GetOK(upReady, feedTray1, feedTray2, use11, use22);
                        if (!CheckFlowCondition()) return;
                    }
                }

                int okcount1 = recycleTray1.Helper.Count(c => c.Status == CellStatus.HasProduct);
                int okcount2 = recycleTray2.Helper.Count(c => c.Status == CellStatus.HasProduct);
                int buffercount1 = _bufferTray1.Helper.Count(c => c.Status == CellStatus.HasProduct);
                int buffercount2 = _bufferTray2.Helper.Count(c => c.Status == CellStatus.HasProduct);
                //此时已经放过NG，所以现在都是OK料
                if (((okcount1 == 2 && okcount2 == 0) || (okcount1 == 0 && okcount2 == 2)) && (GlobalVariable.IsGrrMode || GlobalVariable.IsCosmeticMode))
                {
                    bool upReady = false;
                    #region 确定上下层
                    if (_isFront)
                    {
                        //接管了arm模组
                        while ((!CheckSignal("精定位移载1", $"Arm1精定位到位") ||
                                !CheckSignal("精定位移载1", $"Arm2精定位到位")) &&
                                !IsBreak())
                        {
                            Thread.Sleep(20);
                        }
                        upReady = (_flowManager.SelectFlow("精定位移载1") as PrecisionLogic).GetTwoLayerInPositionStatus();
                    }
                    else
                    {
                        //接管了arm模组
                        while ((!CheckSignal("精定位移载2", $"Arm3精定位到位") ||
                                !CheckSignal("精定位移载2", $"Arm4精定位到位")) &&
                                !IsBreak())
                        {
                            Thread.Sleep(20);
                        }
                        upReady = (_flowManager.SelectFlow("精定位移载2") as PrecisionLogic).GetTwoLayerInPositionStatus();
                    }
                    #endregion
                    if (GlobalVariable.IsGrrMode)
                    {
                        if (recycleTray2.Helper.Any(c => c.Status == CellStatus.HasProduct) &&
                            (GlobalVariable.SN2TestCount[recycleTray2.Helper.GetCell(0).SN][0] == GlobalVariable.TesterNo2GrrTimesSingle[0] &&
                             GlobalVariable.SN2TestCount[recycleTray2.Helper.GetCell(1).SN][0] == GlobalVariable.TesterNo2GrrTimesSingle[0] &&
                             GlobalVariable.SN2TestCount[recycleTray2.Helper.GetCell(0).SN][1] == GlobalVariable.TesterNo2GrrTimesSingle[1] &&
                             GlobalVariable.SN2TestCount[recycleTray2.Helper.GetCell(1).SN][1] == GlobalVariable.TesterNo2GrrTimesSingle[1] &&
                             GlobalVariable.SN2TestCount[recycleTray2.Helper.GetCell(0).SN][2] == GlobalVariable.TesterNo2GrrTimesSingle[2] &&
                             GlobalVariable.SN2TestCount[recycleTray2.Helper.GetCell(1).SN][2] == GlobalVariable.TesterNo2GrrTimesSingle[2]))
                        {
                            //满5遍了，开始调换穴位，再测5遍
                            //也即第6遍开始的时候，调换一下穴位
                            PutBuffer(_bufferTray2, "缓存矩阵", _isFront ? GlobalVariable.BufferTray2UIFront : GlobalVariable.BufferTray2UIBack, 1, $"吸嘴{3 + 1}", 1, recycleTray2);
                            if (!CheckFlowCondition()) return;
                            PutBuffer(_bufferTray2, "缓存矩阵", _isFront ? GlobalVariable.BufferTray2UIFront : GlobalVariable.BufferTray2UIBack, 1, $"吸嘴{3 + 0}", 0, recycleTray2);
                            if (!CheckFlowCondition()) return;
                            GetBuffer(_bufferTray2, "缓存矩阵", _isFront ? GlobalVariable.BufferTray2UIFront : GlobalVariable.BufferTray2UIBack, 1, $"吸嘴{3 + 0}", 0, recycleTray2);
                            if (!CheckFlowCondition()) return;
                            GetBuffer(_bufferTray2, "缓存矩阵", _isFront ? GlobalVariable.BufferTray2UIFront : GlobalVariable.BufferTray2UIBack, 1, $"吸嘴{3 + 1}", 1, recycleTray2);
                            if (!CheckFlowCondition()) return;

                            if (!GlobalVariable.SN2FinishStatus.ContainsKey(recycleTray2.Helper.GetCell(0).SN))
                                GlobalVariable.SN2FinishStatus.Add(recycleTray2.Helper.GetCell(0).SN, new bool[2] { true, false });
                            if (!GlobalVariable.SN2FinishStatus.ContainsKey(recycleTray2.Helper.GetCell(1).SN))
                                GlobalVariable.SN2FinishStatus.Add(recycleTray2.Helper.GetCell(1).SN, new bool[2] { true, false });
                        }
                        if (recycleTray2.Helper.Any(c => c.Status == CellStatus.HasProduct) &&
                            (GlobalVariable.SN2TestCount[recycleTray2.Helper.GetCell(0).SN][0] == 2 * GlobalVariable.TesterNo2GrrTimesSingle[0] &&
                             GlobalVariable.SN2TestCount[recycleTray2.Helper.GetCell(1).SN][0] == 2 * GlobalVariable.TesterNo2GrrTimesSingle[0] &&
                             GlobalVariable.SN2TestCount[recycleTray2.Helper.GetCell(0).SN][1] == 2 * GlobalVariable.TesterNo2GrrTimesSingle[1] &&
                             GlobalVariable.SN2TestCount[recycleTray2.Helper.GetCell(1).SN][1] == 2 * GlobalVariable.TesterNo2GrrTimesSingle[1] &&
                             GlobalVariable.SN2TestCount[recycleTray2.Helper.GetCell(0).SN][2] == 2 * GlobalVariable.TesterNo2GrrTimesSingle[2] &&
                             GlobalVariable.SN2TestCount[recycleTray2.Helper.GetCell(1).SN][2] == 2 * GlobalVariable.TesterNo2GrrTimesSingle[2]))
                        {
                            //单侧做完了
                            putABBNG(_abbNGTray, 1, $"吸嘴{3 + 0}", 0, recycleTray2);
                            if (!CheckFlowCondition()) return;
                            putABBNG(_abbNGTray, 1, $"吸嘴{3 + 1}", 1, recycleTray2);
                            if (!CheckFlowCondition()) return;

                            if (_abbNGTray.Helper.Count(c => c.Status == CellStatus.HasProduct) == 6)
                            {
                                startLeft[1] = true;

                                if (startLeft[0] && startLeft[1])
                                {
                                    //结束了
                                    ShowWarnAndPause("Grr结束!请回零后继续!", "系统", true);
                                    if (!CheckFlowCondition()) return;
                                    startLeft = new bool[2] { false, false };
                                    GlobalVariable.IsSystemAlreadyHome = false;
                                }
                                else
                                {

                                    lock (GlobalVariable.SNLock)
                                    {
                                        GlobalVariable.SN2FinishStatus = new Dictionary<string, bool[]>();
                                        GlobalVariable.SN2TestCount = new Dictionary<string, int[]>();
                                    }

                                    for (int i = 0; i < 6 / 2; i++)
                                    {
                                        getABBNG(_abbNGTray, 0, $"吸嘴{3 + 0}", 0, recycleTray1);
                                        if (!CheckFlowCondition()) return;
                                        getABBNG(_abbNGTray, 0, $"吸嘴{3 + 1}", 1, recycleTray1);
                                        if (!CheckFlowCondition()) return;
                                        SingleAxisMove2Point(_ngAxis, "安全位");
                                        //先做左边的重复测试，不调换穴位，不调换治具
                                        bool use11 = recycleTray1.Helper.Any(c => c.Status == CellStatus.HasProduct);
                                        bool use22 = recycleTray2.Helper.Any(c => c.Status == CellStatus.HasProduct);
                                        PutOK(upReady, recycleTray1, recycleTray2,
                                            use11,
                                            use22);
                                        if (!CheckFlowCondition()) return;
                                        DoPosition2(upReady);
                                        GetOK(upReady, feedTray1, feedTray2, use11, use22);
                                        if (!CheckFlowCondition()) return;
                                        (_flowManager.SelectFlow(_isFront ? $"Arm1模组" : $"Arm3模组") as TransferLogic).GoAndGetPutProduct(i);
                                        if (!CheckFlowCondition()) return;
                                    }
                                    string arm = _isFront ? $"Arm1模组" : $"Arm3模组";
                                    int finishIndex = (_flowManager.SelectFlow(arm) as TransferLogic).SelectFinishTester();
                                    while (finishIndex == -1)
                                    {
                                        finishIndex = (_flowManager.SelectFlow(arm) as TransferLogic).SelectFinishTester();
                                        Thread.Sleep(20);
                                    }
                                    (_flowManager.SelectFlow(arm) as TransferLogic).GoAndGetPutProduct(finishIndex);
                                    Thread.Sleep(2000);
                                    goto grrconti;
                                }
                            }
                            else
                                goto grrconti;
                        }

                        string sn2222 = recycleTray1.Helper.GetCell(0).SN;
                        if (recycleTray1.Helper.Any(c => c.Status == CellStatus.HasProduct) &&
                            (GlobalVariable.SN2TestCount[recycleTray1.Helper.GetCell(0).SN][0] == GlobalVariable.TesterNo2GrrTimesSingle[0] &&
                             GlobalVariable.SN2TestCount[recycleTray1.Helper.GetCell(1).SN][0] == GlobalVariable.TesterNo2GrrTimesSingle[0] &&
                             GlobalVariable.SN2TestCount[recycleTray1.Helper.GetCell(0).SN][1] == GlobalVariable.TesterNo2GrrTimesSingle[1] &&
                             GlobalVariable.SN2TestCount[recycleTray1.Helper.GetCell(1).SN][1] == GlobalVariable.TesterNo2GrrTimesSingle[1] &&
                             GlobalVariable.SN2TestCount[recycleTray1.Helper.GetCell(0).SN][2] == GlobalVariable.TesterNo2GrrTimesSingle[2] &&
                             GlobalVariable.SN2TestCount[recycleTray1.Helper.GetCell(1).SN][2] == GlobalVariable.TesterNo2GrrTimesSingle[2]))
                        {
                            //满5遍了，开始调换穴位，再测5遍
                            //也即第6遍开始的时候，调换一下穴位
                            PutBuffer(_bufferTray1, "缓存矩阵", _isFront ? GlobalVariable.BufferTray2UIFront : GlobalVariable.BufferTray2UIBack, 0, $"吸嘴{3 + 1}", 1, recycleTray1);
                            if (!CheckFlowCondition()) return;
                            PutBuffer(_bufferTray1, "缓存矩阵", _isFront ? GlobalVariable.BufferTray2UIFront : GlobalVariable.BufferTray2UIBack, 0, $"吸嘴{3 + 0}", 0, recycleTray1);
                            if (!CheckFlowCondition()) return;
                            GetBuffer(_bufferTray1, "缓存矩阵", _isFront ? GlobalVariable.BufferTray2UIFront : GlobalVariable.BufferTray2UIBack, 0, $"吸嘴{3 + 0}", 0, recycleTray1);
                            if (!CheckFlowCondition()) return;
                            GetBuffer(_bufferTray1, "缓存矩阵", _isFront ? GlobalVariable.BufferTray2UIFront : GlobalVariable.BufferTray2UIBack, 0, $"吸嘴{3 + 1}", 1, recycleTray1);
                            if (!CheckFlowCondition()) return;

                            if (!GlobalVariable.SN2FinishStatus.ContainsKey(recycleTray1.Helper.GetCell(0).SN))
                                GlobalVariable.SN2FinishStatus.Add(recycleTray1.Helper.GetCell(0).SN, new bool[2] { true, false });
                            if (!GlobalVariable.SN2FinishStatus.ContainsKey(recycleTray1.Helper.GetCell(1).SN))
                                GlobalVariable.SN2FinishStatus.Add(recycleTray1.Helper.GetCell(1).SN, new bool[2] { true, false });
                        }
                        if (recycleTray1.Helper.Any(c => c.Status == CellStatus.HasProduct) &&
                            (GlobalVariable.SN2TestCount[recycleTray1.Helper.GetCell(0).SN][0] == 2 * GlobalVariable.TesterNo2GrrTimesSingle[0] &&
                             GlobalVariable.SN2TestCount[recycleTray1.Helper.GetCell(1).SN][0] == 2 * GlobalVariable.TesterNo2GrrTimesSingle[0] &&
                             GlobalVariable.SN2TestCount[recycleTray1.Helper.GetCell(0).SN][1] == 2 * GlobalVariable.TesterNo2GrrTimesSingle[1] &&
                             GlobalVariable.SN2TestCount[recycleTray1.Helper.GetCell(1).SN][1] == 2 * GlobalVariable.TesterNo2GrrTimesSingle[1] &&
                             GlobalVariable.SN2TestCount[recycleTray1.Helper.GetCell(0).SN][2] == 2 * GlobalVariable.TesterNo2GrrTimesSingle[2] &&
                             GlobalVariable.SN2TestCount[recycleTray1.Helper.GetCell(1).SN][2] == 2 * GlobalVariable.TesterNo2GrrTimesSingle[2]))
                        {
                            //单侧做完了
                            putABBNG(_abbNGTray, 0, $"吸嘴{3 + 0}", 0, recycleTray1);
                            if (!CheckFlowCondition()) return;
                            putABBNG(_abbNGTray, 0, $"吸嘴{3 + 1}", 1, recycleTray1);
                            if (!CheckFlowCondition()) return;


                            if (_abbNGTray.Helper.Count(c => c.Status == CellStatus.HasProduct) == 6)
                            {
                                startLeft[0] = true;
                                if (startLeft[0] && startLeft[1])
                                {
                                    //结束了
                                    ShowWarnAndPause("Grr结束!请回零后继续!", "系统", true);
                                    if (!CheckFlowCondition()) return;
                                    GlobalVariable.IsSystemAlreadyHome = false;
                                }
                                else
                                {
                                    lock (GlobalVariable.SNLock)
                                    {
                                        GlobalVariable.SN2FinishStatus = new Dictionary<string, bool[]>();
                                        GlobalVariable.SN2TestCount = new Dictionary<string, int[]>();
                                    }

                                    for (int i = 0; i < 6 / 2; i++)
                                    {
                                        getABBNG(_abbNGTray, 1, $"吸嘴{3 + 0}", 0, recycleTray2);
                                        if (!CheckFlowCondition()) return;
                                        getABBNG(_abbNGTray, 1, $"吸嘴{3 + 1}", 1, recycleTray2);
                                        if (!CheckFlowCondition()) return;
                                        SingleAxisMove2Point(_ngAxis, "安全位");
                                        //先做左边的重复测试，不调换穴位，不调换治具
                                        bool use11 = recycleTray1.Helper.Any(c => c.Status == CellStatus.HasProduct);
                                        bool use22 = recycleTray2.Helper.Any(c => c.Status == CellStatus.HasProduct);
                                        PutOK(upReady, recycleTray1, recycleTray2,
                                            use11,
                                            use22);
                                        if (!CheckFlowCondition()) return;
                                        DoPosition2(upReady);
                                        GetOK(upReady, feedTray1, feedTray2, use11, use22);
                                        if (!CheckFlowCondition()) return;

                                        (_flowManager.SelectFlow(_isFront ? $"Arm2模组" : $"Arm4模组") as TransferLogic).GoAndGetPutProduct(i);
                                        if (!CheckFlowCondition()) return;
                                    }
                                    string arm = _isFront ? $"Arm2模组" : $"Arm4模组";
                                    int finishIndex = (_flowManager.SelectFlow(arm) as TransferLogic).SelectFinishTester();
                                    while (finishIndex == -1)
                                    {
                                        finishIndex = (_flowManager.SelectFlow(arm) as TransferLogic).SelectFinishTester();
                                        Thread.Sleep(20);
                                    }
                                    (_flowManager.SelectFlow(arm) as TransferLogic).GoAndGetPutProduct(finishIndex);
                                    Thread.Sleep(2000);
                                    goto grrconti;
                                }
                            }
                            else
                                goto grrconti;
                        }

                    grrconti:
                        SingleAxisMove2Point(_ngAxis, "安全位");
                        if (!CheckFlowCondition()) return;
                        bool use1 = false;
                        bool use2 = false;
                        if (recycleTray1.Helper.Any(c => c.Status == CellStatus.HasProduct))
                            use1 = true;
                        if (recycleTray2.Helper.Any(c => c.Status == CellStatus.HasProduct))
                            use2 = true;
                        //先做左边的重复测试，不调换穴位，不调换治具
                        PutOK(upReady, recycleTray1, recycleTray2, use1, use2);
                        if (!CheckFlowCondition()) return;
                        DoPosition(upReady);
                        GetOK(upReady, feedTray1, feedTray2, use1, use2);
                        if (!CheckFlowCondition()) return;
                        if (!use1 && !use2)
                        {
                            if (_isFront)
                            {
                                use1 = !CommonMethod.AllArmTesterNoProduct(0);
                                use2 = !CommonMethod.AllArmTesterNoProduct(1);
                            }
                            else
                            {
                                use1 = !CommonMethod.AllArmTesterNoProduct(2);
                                use2 = !CommonMethod.AllArmTesterNoProduct(3);
                            }
                        }
                        //先找idle的治具
                        string armName = "";
                        int headerIndex = -1;
                        if (!startLeft[0])
                        {
                            if (use1)
                            {
                                armName = _isFront ? $"Arm1模组" : $"Arm3模组";
                                headerIndex = _isFront ? 0 : 2;
                            }
                            else
                            {
                                armName = _isFront ? $"Arm2模组" : $"Arm4模组";
                                headerIndex = _isFront ? 1 : 3;
                            }
                        }
                        else
                        {
                            if (use1)
                            {
                                armName = _isFront ? $"Arm1模组" : $"Arm3模组";
                                headerIndex = _isFront ? 0 : 2;
                            }
                            else
                            {
                                armName = _isFront ? $"Arm2模组" : $"Arm4模组";
                                headerIndex = _isFront ? 1 : 3;
                            }
                        }
                        int tt = (_flowManager.SelectFlow(armName) as TransferLogic).SelectIdleTester();
                        int idleFinishTesterIndex = -1;
                        if (tt != -1)
                        {
                            string sn = (_flowManager.SelectFlow(armName) as TransferLogic).GetFeedTray().Helper.GetCell(0).SN;
                            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"当前SN：{sn}", this.Description, 3, _x1.Module));
                            if (GlobalVariable.SN2TestCount == null)
                                GlobalVariable.SN2TestCount = new Dictionary<string, int[]>();
                            //没做过
                            if (GlobalVariable.SN2TestCount.Count == 0 || !GlobalVariable.SN2TestCount.ContainsKey(sn))
                                idleFinishTesterIndex = tt;
                            //做过且不达次数
                            else if ((GlobalVariable.SN2TestCount[sn][tt] < GlobalVariable.TesterNo2GrrTimesSingle[tt] && !GlobalVariable.SN2FinishStatus.ContainsKey(sn)))
                                idleFinishTesterIndex = tt;
                            else if (GlobalVariable.SN2FinishStatus.ContainsKey(sn))
                            {
                                //一个穴位做完了,另一个没做完
                                if (GlobalVariable.SN2FinishStatus[sn][0] && GlobalVariable.SN2TestCount[sn][tt] < 2 * GlobalVariable.TesterNo2GrrTimesSingle[tt])
                                {
                                    idleFinishTesterIndex = tt;
                                }
                                else
                                {
                                    int tt2 = (_flowManager.SelectFlow(armName) as TransferLogic).SelectFinishTester(sn);
                                    while (tt2 == -1)
                                    {
                                        tt2 = (_flowManager.SelectFlow(armName) as TransferLogic).SelectFinishTester(sn);
                                        Thread.Sleep(20);
                                    }
                                    //idle的治具已经不可以了，选完成的
                                    if (tt2 != -1)
                                        idleFinishTesterIndex = tt2;
                                }
                            }
                            else
                            {
                                int tt2 = (_flowManager.SelectFlow(armName) as TransferLogic).SelectFinishTester(sn);
                                while (tt2 == -1)
                                {
                                    tt2 = (_flowManager.SelectFlow(armName) as TransferLogic).SelectFinishTester(sn);
                                    Thread.Sleep(20);
                                }
                                //idle的治具已经不可以了，选完成的
                                if (tt2 != -1)
                                    idleFinishTesterIndex = tt2;
                            }
                        }

                        (_flowManager.SelectFlow(armName) as TransferLogic).GoAndGetPutProduct(idleFinishTesterIndex);
                        if (!CheckFlowCondition()) return;
                    }
                    else if (GlobalVariable.IsCosmeticMode)
                    {
                        #region 确定编号
                        int lastTesterIndex = -1;
                        int doCount = 0;
                        bool use1 = false;
                        bool use2 = false;
                        if (recycleTray1.Helper.Any(c => c.Status == CellStatus.HasProduct))
                            use1 = true;
                        if (recycleTray2.Helper.Any(c => c.Status == CellStatus.HasProduct))
                            use2 = true;
                        string armName = "";
                        int headerIndex = -1;
                        if (_isFront)
                        {
                            armName = use1 ? $"Arm1模组" : $"Arm2模组";
                            headerIndex = use1 ? 0 : 1;
                        }
                        else
                        {
                            armName = use1 ? $"Arm3模组" : $"Arm4模组";
                            headerIndex = use1 ? 2 : 3;
                        }
                        #endregion
                        #region 判断是否达到压测次数
                        if (use1)
                        {
                            doCount = recycleTray1.Helper.GetCell(0).TestedTesters.Count;
                            if (doCount >= SystemConfig.Instance.UsingStatus.CosmeticCount)
                            {
                                GlobalVariable.CosmeticFinishTesterIndex.Add(recycleTray1.Helper.GetCell(0).TestedTesters.Last());
                                for (int i = 0; i < 2; i++)
                                {
                                    putABBNG(_abbNGTray, headerIndex % 2, $"吸嘴{3 + i}", i, recycleTray1);
                                    if (!CheckFlowCondition()) return;
                                }
                                SingleAxisMove2Point(_ngAxis, "安全位");
                            }
                        }
                        else
                        {
                            doCount = recycleTray2.Helper.GetCell(0).TestedTesters.Count;
                            if (doCount >= SystemConfig.Instance.UsingStatus.CosmeticCount)
                            {
                                GlobalVariable.CosmeticFinishTesterIndex.Add(recycleTray2.Helper.GetCell(0).TestedTesters.Last() % 3);
                                for (int i = 0; i < 2; i++)
                                {
                                    putABBNG(_abbNGTray, headerIndex % 2, $"吸嘴{3 + i}", i, recycleTray2);
                                    if (!CheckFlowCondition()) return;
                                }
                                SingleAxisMove2Point(_ngAxis, "安全位");
                            }
                        }
                        if (_abbNGTray.Helper.Count(c => c.Status == CellStatus.HasProduct) >= 6)
                        {
                            ShowWarnAndPause("压测模式结束", "系统", true);
                            GlobalVariable.IsSystemAlreadyHome = false;
                            if (!CheckFlowCondition()) return;
                        }
                        #endregion
                        if (recycleTray1.Helper.Any(c => c.Status == CellStatus.HasProduct) ||
                           recycleTray2.Helper.Any(c => c.Status == CellStatus.HasProduct))
                        {
                            #region 做精定位动作
                            SingleAxisMove2Point(_ngAxis, "安全位");
                            if (!CheckFlowCondition()) return;
                            if (use1)
                            {
                                lastTesterIndex = recycleTray1.Helper.GetCell(0).TestedTesters[0];
                            }
                            else
                            {
                                lastTesterIndex = recycleTray2.Helper.GetCell(0).TestedTesters[0];
                            }
                            //先做左边的重复测试，不调换穴位，不调换治具
                            PutOK(upReady, recycleTray1, recycleTray2, use1, use2);
                            if (!CheckFlowCondition()) return;
                            DoPosition(upReady);
                            GetOK(upReady, feedTray1, feedTray2, use1, use2);
                            if (!CheckFlowCondition()) return;
                            #endregion
                            #region 确定放哪个治具
                            (_flowManager.SelectFlow(armName) as TransferLogic).WaitTesterFinish(headerIndex, lastTesterIndex % 3);
                            if (!CheckFlowCondition()) return;
                            (_flowManager.SelectFlow(armName) as TransferLogic).GoAndGetPutProduct(lastTesterIndex);
                            if (!CheckFlowCondition()) return;
                            #endregion
                        }
                    }
                }
                else
                {
                    //取放buffer
                    if (okcount1 != 2 || okcount2 != 2)
                    {
                        if (okcount1 + okcount2 + buffercount1 + buffercount2 < 4)
                        {
                            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"手上的OK料+buffer的料不够4个，需要放buffer", this.Description, 0, ""));
                            //放Buffer
                            //1头优先放buffer1，2头优先放buffer2
                            //1头有1个OK且buffer1够放
                            if (okcount1 == 1 && _bufferTray1.Helper.Count(c => c.Status == CellStatus.NoProduct) > 0)
                            {
                                LogHelper.Instance.Log(this.Description, "放Buffer开始", MessageLevel.CT);
                                PutBuffer(_bufferTray1, "缓存矩阵", _isFront ? GlobalVariable.BufferTray1UIFront : GlobalVariable.BufferTray1UIBack, 0, $"吸嘴{3 + recycleTray1.Helper.GetFirstIndex(CellStatus.HasProduct)}", recycleTray1.Helper.GetFirstIndex(CellStatus.HasProduct), recycleTray1);
                                LogHelper.Instance.Log(this.Description, "放Buffer结束", MessageLevel.CT);
                            }
                            //1头有1个OK且buffer1不够放
                            else if (okcount1 == 1 && _bufferTray1.Helper.Count(c => c.Status == CellStatus.NoProduct) == 0)
                            {
                                LogHelper.Instance.Log(this.Description, "放Buffer开始", MessageLevel.CT);
                                PutBuffer(_bufferTray2, "缓存矩阵对侧", _isFront ? GlobalVariable.BufferTray2UIFront : GlobalVariable.BufferTray2UIBack, 0, $"吸嘴{3 + recycleTray1.Helper.GetFirstIndex(CellStatus.HasProduct)}", recycleTray1.Helper.GetFirstIndex(CellStatus.HasProduct), recycleTray1);
                                LogHelper.Instance.Log(this.Description, "放Buffer结束", MessageLevel.CT);
                                //走到左头放OK位
                                string xpos = "";
                                if (_isFront)
                                {
                                    xpos = "Arm1精定位上层取料位置";
                                }
                                else
                                {
                                    xpos = "Arm3精定位上层取料位置";
                                }
                                SingleAxisMove2Point(_x1, xpos);
                                if (!CheckFlowCondition()) return;
                            }
                            else if (okcount1 == 2)
                            {
                                //buffer1只能放一个
                                if (_bufferTray1.Helper.Count(c => c.Status == CellStatus.NoProduct) == 1)
                                {
                                    LogHelper.Instance.Log(this.Description, "放Buffer开始", MessageLevel.CT);
                                    PutBuffer(_bufferTray1, "缓存矩阵", _isFront ? GlobalVariable.BufferTray1UIFront : GlobalVariable.BufferTray1UIBack, 0, $"吸嘴{3 + recycleTray1.Helper.GetFirstIndex(CellStatus.HasProduct)}", recycleTray1.Helper.GetFirstIndex(CellStatus.HasProduct), recycleTray1);
                                    LogHelper.Instance.Log(this.Description, "放Buffer结束", MessageLevel.CT);

                                    LogHelper.Instance.Log(this.Description, "放Buffer开始", MessageLevel.CT);
                                    PutBuffer(_bufferTray2, "缓存矩阵对侧", _isFront ? GlobalVariable.BufferTray2UIFront : GlobalVariable.BufferTray2UIBack, 0, $"吸嘴{3 + recycleTray1.Helper.GetFirstIndex(CellStatus.HasProduct)}", recycleTray1.Helper.GetFirstIndex(CellStatus.HasProduct), recycleTray1);
                                    LogHelper.Instance.Log(this.Description, "放Buffer结束", MessageLevel.CT);

                                    //走到左头放OK位
                                    string xpos = "";
                                    if (_isFront)
                                    {
                                        xpos = "Arm1精定位上层取料位置";
                                    }
                                    else
                                    {
                                        xpos = "Arm3精定位上层取料位置";
                                    }
                                    SingleAxisMove2Point(_x1, xpos);
                                    if (!CheckFlowCondition()) return;
                                }
                                //buffer1可以放两个
                                else if (_bufferTray1.Helper.Count(c => c.Status == CellStatus.NoProduct) == 2)
                                {
                                    LogHelper.Instance.Log(this.Description, "放Buffer开始", MessageLevel.CT);
                                    PutBuffer(_bufferTray1, "缓存矩阵", _isFront ? GlobalVariable.BufferTray1UIFront : GlobalVariable.BufferTray1UIBack, 0, $"吸嘴{3 + recycleTray1.Helper.GetFirstIndex(CellStatus.HasProduct)}", recycleTray1.Helper.GetFirstIndex(CellStatus.HasProduct), recycleTray1);
                                    LogHelper.Instance.Log(this.Description, "放Buffer结束", MessageLevel.CT);

                                    LogHelper.Instance.Log(this.Description, "放Buffer开始", MessageLevel.CT);
                                    PutBuffer(_bufferTray1, "缓存矩阵", _isFront ? GlobalVariable.BufferTray1UIFront : GlobalVariable.BufferTray1UIBack, 0, $"吸嘴{3 + recycleTray1.Helper.GetFirstIndex(CellStatus.HasProduct)}", recycleTray1.Helper.GetFirstIndex(CellStatus.HasProduct), recycleTray1);
                                    LogHelper.Instance.Log(this.Description, "放Buffer结束", MessageLevel.CT);
                                }
                                else if (_bufferTray1.Helper.Count(c => c.Status == CellStatus.NoProduct) == 0)
                                {
                                    LogHelper.Instance.Log(this.Description, "放Buffer开始", MessageLevel.CT);
                                    PutBuffer(_bufferTray2, "缓存矩阵对侧", _isFront ? GlobalVariable.BufferTray2UIFront : GlobalVariable.BufferTray2UIBack, 0, $"吸嘴{3 + recycleTray1.Helper.GetFirstIndex(CellStatus.HasProduct)}", recycleTray1.Helper.GetFirstIndex(CellStatus.HasProduct), recycleTray1);
                                    LogHelper.Instance.Log(this.Description, "放Buffer结束", MessageLevel.CT);

                                    LogHelper.Instance.Log(this.Description, "放Buffer开始", MessageLevel.CT);
                                    PutBuffer(_bufferTray2, "缓存矩阵对侧", _isFront ? GlobalVariable.BufferTray2UIFront : GlobalVariable.BufferTray2UIBack, 0, $"吸嘴{3 + recycleTray1.Helper.GetFirstIndex(CellStatus.HasProduct)}", recycleTray1.Helper.GetFirstIndex(CellStatus.HasProduct), recycleTray1);
                                    LogHelper.Instance.Log(this.Description, "放Buffer结束", MessageLevel.CT);

                                    //走到左头放OK位
                                    string xpos = "";
                                    if (_isFront)
                                    {
                                        xpos = "Arm1精定位上层取料位置";
                                    }
                                    else
                                    {
                                        xpos = "Arm3精定位上层取料位置";
                                    }
                                    SingleAxisMove2Point(_x1, xpos);
                                    if (!CheckFlowCondition()) return;
                                }
                            }

                            if (okcount2 == 1 && _bufferTray2.Helper.Count(c => c.Status == CellStatus.NoProduct) > 0)
                            {
                                LogHelper.Instance.Log(this.Description, "放Buffer开始", MessageLevel.CT);
                                PutBuffer(_bufferTray2, "缓存矩阵", _isFront ? GlobalVariable.BufferTray2UIFront : GlobalVariable.BufferTray2UIBack, 1, $"吸嘴{3 + recycleTray2.Helper.GetFirstIndex(CellStatus.HasProduct)}", recycleTray2.Helper.GetFirstIndex(CellStatus.HasProduct), recycleTray2);
                                LogHelper.Instance.Log(this.Description, "放Buffer结束", MessageLevel.CT);
                            }
                            else if (okcount2 == 1 && _bufferTray2.Helper.Count(c => c.Status == CellStatus.NoProduct) == 0)
                            {
                                LogHelper.Instance.Log(this.Description, "放Buffer开始", MessageLevel.CT);
                                PutBuffer(_bufferTray1, "缓存矩阵对侧", _isFront ? GlobalVariable.BufferTray1UIFront : GlobalVariable.BufferTray1UIBack, 1, $"吸嘴{3 + recycleTray2.Helper.GetFirstIndex(CellStatus.HasProduct)}", recycleTray2.Helper.GetFirstIndex(CellStatus.HasProduct), recycleTray2);
                                LogHelper.Instance.Log(this.Description, "放Buffer结束", MessageLevel.CT);
                                //走到左头放OK位
                                string xpos = "";
                                if (_isFront)
                                {
                                    xpos = "Arm2精定位上层取料位置";
                                }
                                else
                                {
                                    xpos = "Arm4精定位上层取料位置";
                                }
                                SingleAxisMove2Point(_x2, xpos);
                                if (!CheckFlowCondition()) return;
                            }
                            else if (okcount2 == 2)
                            {
                                //buffer2只能放一个
                                if (_bufferTray2.Helper.Count(c => c.Status == CellStatus.NoProduct) == 1)
                                {
                                    LogHelper.Instance.Log(this.Description, "放Buffer开始", MessageLevel.CT);
                                    PutBuffer(_bufferTray2, "缓存矩阵", _isFront ? GlobalVariable.BufferTray2UIFront : GlobalVariable.BufferTray2UIBack, 1, $"吸嘴{3 + recycleTray2.Helper.GetFirstIndex(CellStatus.HasProduct)}", recycleTray2.Helper.GetFirstIndex(CellStatus.HasProduct), recycleTray2);
                                    LogHelper.Instance.Log(this.Description, "放Buffer结束", MessageLevel.CT);

                                    LogHelper.Instance.Log(this.Description, "放Buffer开始", MessageLevel.CT);
                                    PutBuffer(_bufferTray1, "缓存矩阵对侧", _isFront ? GlobalVariable.BufferTray1UIFront : GlobalVariable.BufferTray1UIBack, 1, $"吸嘴{3 + recycleTray2.Helper.GetFirstIndex(CellStatus.HasProduct)}", recycleTray2.Helper.GetFirstIndex(CellStatus.HasProduct), recycleTray2);
                                    LogHelper.Instance.Log(this.Description, "放Buffer结束", MessageLevel.CT);
                                    //走到左头放OK位
                                    string xpos = "";
                                    if (_isFront)
                                    {
                                        xpos = "Arm2精定位上层取料位置";
                                    }
                                    else
                                    {
                                        xpos = "Arm4精定位上层取料位置";
                                    }
                                    SingleAxisMove2Point(_x2, xpos);
                                    if (!CheckFlowCondition()) return;
                                }
                                //buffer1可以放两个
                                else if (_bufferTray2.Helper.Count(c => c.Status == CellStatus.NoProduct) == 2)
                                {
                                    LogHelper.Instance.Log(this.Description, "放Buffer开始", MessageLevel.CT);
                                    PutBuffer(_bufferTray2, "缓存矩阵", _isFront ? GlobalVariable.BufferTray2UIFront : GlobalVariable.BufferTray2UIBack, 1, $"吸嘴{3 + recycleTray2.Helper.GetFirstIndex(CellStatus.HasProduct)}", recycleTray2.Helper.GetFirstIndex(CellStatus.HasProduct), recycleTray2);
                                    LogHelper.Instance.Log(this.Description, "放Buffer结束", MessageLevel.CT);

                                    LogHelper.Instance.Log(this.Description, "放Buffer开始", MessageLevel.CT);
                                    PutBuffer(_bufferTray2, "缓存矩阵", _isFront ? GlobalVariable.BufferTray2UIFront : GlobalVariable.BufferTray2UIBack, 1, $"吸嘴{3 + recycleTray2.Helper.GetFirstIndex(CellStatus.HasProduct)}", recycleTray2.Helper.GetFirstIndex(CellStatus.HasProduct), recycleTray2);
                                    LogHelper.Instance.Log(this.Description, "放Buffer结束", MessageLevel.CT);
                                }
                                else if (_bufferTray2.Helper.Count(c => c.Status == CellStatus.NoProduct) == 0)
                                {
                                    LogHelper.Instance.Log(this.Description, "放Buffer开始", MessageLevel.CT);
                                    PutBuffer(_bufferTray1, "缓存矩阵对侧", _isFront ? GlobalVariable.BufferTray1UIFront : GlobalVariable.BufferTray1UIBack, 1, $"吸嘴{3 + recycleTray2.Helper.GetFirstIndex(CellStatus.HasProduct)}", recycleTray2.Helper.GetFirstIndex(CellStatus.HasProduct), recycleTray2);
                                    LogHelper.Instance.Log(this.Description, "放Buffer结束", MessageLevel.CT);

                                    LogHelper.Instance.Log(this.Description, "放Buffer开始", MessageLevel.CT);
                                    PutBuffer(_bufferTray1, "缓存矩阵对侧", _isFront ? GlobalVariable.BufferTray1UIFront : GlobalVariable.BufferTray1UIBack, 1, $"吸嘴{3 + recycleTray2.Helper.GetFirstIndex(CellStatus.HasProduct)}", recycleTray2.Helper.GetFirstIndex(CellStatus.HasProduct), recycleTray2);
                                    LogHelper.Instance.Log(this.Description, "放Buffer结束", MessageLevel.CT);
                                    //走到左头放OK位
                                    string xpos = "";
                                    if (_isFront)
                                    {
                                        xpos = "Arm2精定位上层取料位置";
                                    }
                                    else
                                    {
                                        xpos = "Arm4精定位上层取料位置";
                                    }
                                    SingleAxisMove2Point(_x2, xpos);
                                    if (!CheckFlowCondition()) return;
                                }
                            }
                        }
                        else
                        {
                            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"手上的OK料+buffer的料大于4个，取buffer", this.Description, 0, ""));
                            //取Buffer
                            //头1料不足且buffer1有料可取
                            if (okcount1 < 2 && _bufferTray1.Helper.Count(c => c.Status == CellStatus.HasProduct) > 0)
                            {
                                for (int i = 0; i < 2; i++)
                                {
                                    if (recycleTray1.Helper.GetCell(i).Status == CellStatus.NoProduct)
                                    {
                                        LogHelper.Instance.Log(this.Description, "取Buffer", MessageLevel.CT);
                                        GetBuffer(_bufferTray1, "缓存矩阵", _isFront ? GlobalVariable.BufferTray1UIFront : GlobalVariable.BufferTray1UIBack, 0, $"吸嘴{3 + i}", i, recycleTray1);
                                        LogHelper.Instance.Log(this.Description, "取Buffer结束", MessageLevel.CT);
                                    }
                                    if (_bufferTray1.Helper.Count(c => c.Status == CellStatus.HasProduct) == 0)
                                        break;
                                }
                            }
                            //在查一次头1
                            okcount1 = recycleTray1.Helper.Count(c => c.Status == CellStatus.HasProduct);
                            //还是不足2个
                            if (okcount1 < 2)
                            {
                                for (int i = 0; i < 2; i++)
                                {
                                    if (recycleTray1.Helper.GetCell(i).Status == CellStatus.NoProduct)
                                    {
                                        LogHelper.Instance.Log(this.Description, "取Buffer", MessageLevel.CT);
                                        GetBuffer(_bufferTray2, "缓存矩阵对侧", _isFront ? GlobalVariable.BufferTray2UIFront : GlobalVariable.BufferTray2UIBack, 0, $"吸嘴{3 + i}", i, recycleTray1);
                                        LogHelper.Instance.Log(this.Description, "取Buffer结束", MessageLevel.CT);
                                        //走到左头放OK位
                                        string xpos = "";
                                        if (_isFront)
                                        {
                                            xpos = "Arm1精定位上层放料位置";
                                        }
                                        else
                                        {
                                            xpos = "Arm3精定位上层放料位置";
                                        }
                                        SingleAxisMove2Point(_x1, xpos);
                                        if (!CheckFlowCondition()) return;
                                    }
                                    if (_bufferTray2.Helper.Count(c => c.Status == CellStatus.HasProduct) == 0)
                                        break;
                                }
                            }

                            //头2料不足且buffer2有料可取
                            if (okcount2 < 2 && _bufferTray2.Helper.Count(c => c.Status == CellStatus.HasProduct) > 0)
                            {
                                for (int i = 0; i < 2; i++)
                                {
                                    if (recycleTray2.Helper.GetCell(i).Status == CellStatus.NoProduct)
                                    {
                                        LogHelper.Instance.Log(this.Description, "取Buffer", MessageLevel.CT);
                                        GetBuffer(_bufferTray2, "缓存矩阵", _isFront ? GlobalVariable.BufferTray2UIFront : GlobalVariable.BufferTray2UIBack, 1, $"吸嘴{3 + i}", i, recycleTray2);
                                        LogHelper.Instance.Log(this.Description, "取Buffer结束", MessageLevel.CT);
                                    }
                                    if (_bufferTray2.Helper.Count(c => c.Status == CellStatus.HasProduct) == 0)
                                        break;
                                }
                            }
                            //在查一次头1
                            okcount2 = recycleTray2.Helper.Count(c => c.Status == CellStatus.HasProduct);
                            //还是不足2个
                            if (okcount2 < 2)
                            {
                                for (int i = 0; i < 2; i++)
                                {
                                    if (recycleTray2.Helper.GetCell(i).Status == CellStatus.NoProduct)
                                    {
                                        LogHelper.Instance.Log(this.Description, "取Buffer", MessageLevel.CT);
                                        GetBuffer(_bufferTray1, "缓存矩阵对侧", _isFront ? GlobalVariable.BufferTray1UIFront : GlobalVariable.BufferTray1UIBack, 1, $"吸嘴{3 + i}", i, recycleTray2);
                                        LogHelper.Instance.Log(this.Description, "取Buffer结束", MessageLevel.CT);
                                        //走到右头放OK位
                                        string xpos = "";
                                        if (_isFront)
                                        {
                                            xpos = "Arm2精定位上层放料位置";
                                        }
                                        else
                                        {
                                            xpos = "Arm4精定位上层放料位置";
                                        }
                                        SingleAxisMove2Point(_x2, xpos);
                                        if (!CheckFlowCondition()) return;
                                    }
                                    if (_bufferTray1.Helper.Count(c => c.Status == CellStatus.HasProduct) == 0)
                                        break;
                                }
                            }
                        }
                    }
                    SingleAxisMove2Point(_ngAxis, "安全位");
                    if (!CheckFlowCondition()) return;
                    //放OK
                    if (recycleTray1.Helper.Count(c => c.Status == CellStatus.HasProduct) == 2 &&
                        recycleTray2.Helper.Count(c => c.Status == CellStatus.HasProduct) == 2)
                    {
                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"手上有待下的OK料，需要放精定位去回收", this.Description, 0, ""));
                        bool upReady = false;
                        if (_isFront)
                        {
                            //接管了arm模组
                            while ((!CheckSignal("精定位移载1", $"Arm1精定位到位") ||
                                    !CheckSignal("精定位移载1", $"Arm2精定位到位")) &&
                                    !IsBreak())
                            {
                                Thread.Sleep(20);
                            }
                            upReady = (_flowManager.SelectFlow("精定位移载1") as PrecisionLogic).GetTwoLayerInPositionStatus();
                        }
                        else
                        {
                            //接管了arm模组
                            while ((!CheckSignal("精定位移载2", $"Arm3精定位到位") ||
                                    !CheckSignal("精定位移载2", $"Arm4精定位到位")) &&
                                    !IsBreak())
                            {
                                Thread.Sleep(20);
                            }
                            upReady = (_flowManager.SelectFlow("精定位移载2") as PrecisionLogic).GetTwoLayerInPositionStatus();
                        }
                        LogHelper.Instance.Log(this.Description, "放OK", MessageLevel.CT);
                        PutOK(upReady, recycleTray1, recycleTray2);
                        LogHelper.Instance.Log(this.Description, "放OK结束", MessageLevel.CT);
                        if (!CheckFlowCondition()) return;
                        if (CommonMethod.AllPrecisionFeedNoProduct(_isFront ? 0 : 1, upReady))
                        {
                            if (_isFront)
                            {
                                AxisMoveSimultaneously(new List<Axis>()
                                {
                                    MachineResource.Instance.MachineAxis["Arm1Z轴"],
                                    MachineResource.Instance.MachineAxis["Arm2Z轴"],
                                }, "待机位");
                            }
                            else
                            {
                                AxisMoveSimultaneously(new List<Axis>()
                                {
                                    MachineResource.Instance.MachineAxis["Arm3Z轴"],
                                    MachineResource.Instance.MachineAxis["Arm4Z轴"],
                                }, "待机位");
                            }
                        }
                    }
                    else
                    {
                        //MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"手上没有足够的OK料？", this.Description, 0, ""));
                        //ShowWarnAndPause("逻辑异常", _x1.Module);
                    }
                }

                if (_isFront)
                {
                    SetSignal($"Arm1放料结束");
                    SetSignal($"Arm2放料结束");
                }
                else
                {
                    SetSignal($"Arm3放料结束");
                    SetSignal($"Arm4放料结束");
                }
            }
        }
        public void SpotCheck2()
        {
            if (!CheckFlowCondition()) return;

            if (SystemConfig.Instance.SpotSNs.UseTwoProduct)
            {
                #region 点检前准备
                _spotCheckTray.Helper.NewFullTray();
                for (int i = 0; i < 4; i++)
                {
                    _spotCheckTray.Helper.SetCellBarcode(i, $"00{i + 1}");
                }
                _abbNGTray.Helper.NewFullTray();
                for (int i = 0; i < 4; i++)
                {
                    _abbNGTray.Helper.SetCellBarcode(i, $"DUMMY-00{i + 1}");
                }
                for (int i = 12; i < 16; i++)
                {
                    _abbNGTray.Helper.SetCellBarcode(i, _isFront ? SystemConfig.Instance.SpotSNs.SNFront[i - 12] : SystemConfig.Instance.SpotSNs.SNBack[i - 12]);
                }
                #endregion
                #region 确定Arm
                Dictionary<int, bool[]> spotCheckStatusLeft = new Dictionary<int, bool[]>();
                spotCheckStatusLeft.Add(0, new bool[SystemConfig.Instance.SpotSNs.DummyAuditTimes]);
                spotCheckStatusLeft.Add(1, new bool[SystemConfig.Instance.SpotSNs.DummyAuditTimes]);
                spotCheckStatusLeft.Add(2, new bool[SystemConfig.Instance.SpotSNs.DummyAuditTimes]);
                Dictionary<int, bool[]> spotCheckStatusRight = new Dictionary<int, bool[]>();
                spotCheckStatusRight.Add(0, new bool[SystemConfig.Instance.SpotSNs.DummyAuditTimes]);
                spotCheckStatusRight.Add(1, new bool[SystemConfig.Instance.SpotSNs.DummyAuditTimes]);
                spotCheckStatusRight.Add(2, new bool[SystemConfig.Instance.SpotSNs.DummyAuditTimes]);

                Tray recycleTray1 = null;
                Tray recycleTray2 = null;
                Tray feedTray1 = null;
                Tray feedTray2 = null;
                string armLeft = "";
                string armRight = "";
                if (_isFront)
                {
                    recycleTray1 = (_flowManager.SelectFlow("Arm1模组") as TransferLogic).GetRecycleTray();
                    recycleTray2 = (_flowManager.SelectFlow("Arm2模组") as TransferLogic).GetRecycleTray();
                    feedTray1 = (_flowManager.SelectFlow("Arm1模组") as TransferLogic).GetFeedTray();
                    feedTray2 = (_flowManager.SelectFlow("Arm2模组") as TransferLogic).GetFeedTray();

                    armLeft = "Arm1模组";
                    armRight = "Arm2模组";
                }
                else
                {
                    recycleTray1 = (_flowManager.SelectFlow("Arm3模组") as TransferLogic).GetRecycleTray();
                    recycleTray2 = (_flowManager.SelectFlow("Arm4模组") as TransferLogic).GetRecycleTray();
                    feedTray1 = (_flowManager.SelectFlow("Arm3模组") as TransferLogic).GetFeedTray();
                    feedTray2 = (_flowManager.SelectFlow("Arm4模组") as TransferLogic).GetFeedTray();

                    armLeft = "Arm3模组";
                    armRight = "Arm4模组";
                }
                #endregion
                #region 确定当前上下层
                bool upReady = false;
                if (_isFront)
                {
                    upReady = (_flowManager.SelectFlow("精定位移载1") as PrecisionLogic).GetTwoLayerInPositionStatus();
                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"当前上下层状态：{upReady}", this.Description, 0, ""));
                }
                else
                {
                    upReady = (_flowManager.SelectFlow("精定位移载2") as PrecisionLogic).GetTwoLayerInPositionStatus();
                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"当前上下层状态：{upReady}", this.Description, 0, ""));
                }
                #endregion
                #region 各自取料
                getABBNG(_abbNGTray, 0, $"吸嘴{3 + 0}", 0, recycleTray1);
                if (!CheckFlowCondition()) return;
                getABBNG(_abbNGTray, 0, $"吸嘴{3 + 1}", 1, recycleTray1);
                if (!CheckFlowCondition()) return;

                getABBNG(_abbNGTray, 1, $"吸嘴{3 + 0}", 0, recycleTray2);
                if (!CheckFlowCondition()) return;
                getABBNG(_abbNGTray, 1, $"吸嘴{3 + 1}", 1, recycleTray2);
                if (!CheckFlowCondition()) return;

                SingleAxisMove2Point(_ngAxis, "安全位");
                if (!CheckFlowCondition()) return;
                bool use1 = false;
                bool use2 = false;
                if (recycleTray1.Helper.Any(c => c.Status == CellStatus.HasProduct))
                    use1 = true;
                if (recycleTray2.Helper.Any(c => c.Status == CellStatus.HasProduct))
                    use2 = true;
                //先做左边的重复测试，不调换穴位，不调换治具
                PutOK(upReady, recycleTray1, recycleTray2, use1, use2);
                if (!CheckFlowCondition()) return;
                DoPosition(upReady);
                GetOK(upReady, feedTray1, feedTray2, use1, use2);
                if (!CheckFlowCondition()) return;

                #endregion
                #region 各自循环放料
                Task task1 = new Task(() =>
                {
                    if (true)
                    {
                        foreach (var item in spotCheckStatusLeft)
                        {
                            int testerIndex = _isFront ? 0 + item.Key : 6 + item.Key;

                            if (SystemConfig.Instance.UsingStatus.TesterInUseStatus[testerIndex])
                            {
                                //当前治具还有没做完的点检次数
                                for (int i = 0; i < item.Value.Length; i++)
                                {
                                    if (!item.Value[i])
                                    {
                                        (_flowManager.SelectFlow(armLeft) as TransferLogic).GoAndGetPutProduct(item.Key);
                                        if (!CheckFlowCondition()) return;
                                        int h = _isFront ? 0 : 2;
                                        if (recycleTray1.Helper.Any(c => c.Status == CellStatus.HasProduct))
                                        {
                                            TesterLogic testerLogic = _flowManager.SelectFlow($"测试模组{h + 1}{item.Key + 1}") as TesterLogic;
                                            (_flowManager.SelectFlow(armLeft) as TransferLogic).FeedTesterByUnload(item.Key, testerLogic);
                                        }
                                        Thread.Sleep(1000);
                                        (_flowManager.SelectFlow(armLeft) as TransferLogic).WaitTesterFinish(h, item.Key);
                                        if (!CheckFlowCondition()) return;
                                        item.Value[i] = true;
                                        //最后一次了，需要把料取起来
                                        if (i == item.Value.Length - 1)
                                        {
                                            (_flowManager.SelectFlow(armLeft) as TransferLogic).GoAndGetPutProduct(item.Key);
                                        }
                                    }
                                }

                                bool finish = true;
                                foreach (var status in spotCheckStatusLeft)
                                {
                                    int testerIndex2 = _isFront ? 0 + status.Key : 6 + status.Key;

                                    if (SystemConfig.Instance.UsingStatus.TesterInUseStatus[_isFront ? testerIndex2 : testerIndex2 + 6])
                                    {
                                        if (status.Value.Any(c => !c))
                                        {
                                            finish = false;
                                            break;
                                        }
                                    }
                                }

                                if (!finish)
                                {
                                    //做完一个治具后，需要把产品放到精定位再重定位一下
                                    use1 = true;
                                    use2 = false;
                                    PutOKLeft(upReady, recycleTray1);
                                    if (!CheckFlowCondition()) return;
                                    DoPositionLeft(upReady);
                                    GetOKLeft(upReady, feedTray1);
                                    if (!CheckFlowCondition()) return;
                                }
                                else
                                    break;
                            }
                        }
                    }
                    else
                    {
                        int start = 0;
                    retry:
                        DoSpotSingleLeft(spotCheckStatusLeft, start, armLeft, upReady, recycleTray1, recycleTray2, feedTray2, feedTray2);

                        bool finish = true;
                        foreach (var status in spotCheckStatusLeft)
                        {
                            int testerIndex2 = _isFront ? 0 + status.Key : 6 + status.Key;

                            if (SystemConfig.Instance.UsingStatus.TesterInUseStatus[_isFront ? testerIndex2 : testerIndex2 + 6])
                            {
                                if (status.Value.Any(c => !c))
                                {
                                    finish = false;
                                    break;
                                }
                            }
                        }

                        if (!finish)
                        {
                            //做完一个治具后，需要把产品放到精定位再重定位一下
                            use1 = true;
                            use2 = false;
                            PutOKLeft(upReady, recycleTray1);
                            if (!CheckFlowCondition()) return;
                            //DoPosition(upReady);
                            GetOKLeft(upReady, feedTray1);
                            if (!CheckFlowCondition()) return;
                            start++;
                            goto retry;
                        }
                        else
                            return;
                    }
                });
                task1.Start();
                Task task2 = new Task(() =>
                {
                    if (true)
                    {
                        foreach (var item in spotCheckStatusRight)
                        {
                            int testerIndex = _isFront ? 0 + item.Key + 3 : 6 + item.Key + 3;
                            if (SystemConfig.Instance.UsingStatus.TesterInUseStatus[testerIndex])
                            {
                                //当前治具还有没做完的点检次数
                                for (int i = 0; i < item.Value.Length; i++)
                                {
                                    if (!item.Value[i])
                                    {
                                        (_flowManager.SelectFlow(armRight) as TransferLogic).GoAndGetPutProduct(item.Key);
                                        if (!CheckFlowCondition()) return;
                                        int h = _isFront ? 1 : 3;
                                        if (recycleTray2.Helper.Any(c => c.Status == CellStatus.HasProduct))
                                        {
                                            TesterLogic testerLogic = _flowManager.SelectFlow($"测试模组{h + 1}{item.Key + 1}") as TesterLogic;
                                            (_flowManager.SelectFlow(armRight) as TransferLogic).FeedTesterByUnload(item.Key, testerLogic);
                                        }
                                        (_flowManager.SelectFlow(armRight) as TransferLogic).WaitTesterFinish(h, item.Key);
                                        if (!CheckFlowCondition()) return;
                                        item.Value[i] = true;
                                        //最后一次了，需要把料取起来
                                        if (i == item.Value.Length - 1)
                                        {
                                            (_flowManager.SelectFlow(armRight) as TransferLogic).GoAndGetPutProduct(item.Key);
                                        }
                                    }
                                }


                                bool finish = true;
                                foreach (var status in spotCheckStatusRight)
                                {
                                    int testerIndex2 = _isFront ? 3 + status.Key : 9 + status.Key;

                                    if (SystemConfig.Instance.UsingStatus.TesterInUseStatus[testerIndex2])
                                    {
                                        if (status.Value.Any(c => !c))
                                        {
                                            finish = false;
                                            break;
                                        }
                                    }
                                }

                                if (!finish)
                                {
                                    //做完一个治具后，需要把产品放到精定位再重定位一下
                                    use1 = false;
                                    use2 = true;
                                    PutOKRight(upReady, recycleTray2);
                                    if (!CheckFlowCondition()) return;
                                    DoPositionRight(upReady);
                                    GetOKRight(upReady, feedTray2);
                                    if (!CheckFlowCondition()) return;
                                }
                                else
                                    break;
                            }
                        }
                    }
                    else
                    {
                        int start = 0;
                    retry:
                        DoSpotSingleRight(spotCheckStatusRight, start, armRight, upReady, recycleTray1, recycleTray2, feedTray2, feedTray2);

                        bool finish = true;
                        foreach (var status in spotCheckStatusRight)
                        {
                            int testerIndex2 = _isFront ? 3 + status.Key : 9 + status.Key;

                            if (SystemConfig.Instance.UsingStatus.TesterInUseStatus[testerIndex2])
                            {
                                if (status.Value.Any(c => !c))
                                {
                                    finish = false;
                                    break;
                                }
                            }
                        }

                        if (!finish)
                        {
                            //做完一个治具后，需要把产品放到精定位再重定位一下
                            use1 = false;
                            use2 = true;
                            PutOKRight(upReady, recycleTray2);
                            if (!CheckFlowCondition()) return;
                            //DoPosition(upReady);
                            GetOKRight(upReady, feedTray2);
                            if (!CheckFlowCondition()) return;
                            start++;
                            goto retry;
                        }
                        else
                            return;
                    }
                });
                task2.Start();
                #endregion
                Task.WaitAll(task1, task2);
                #region 放回
                if (recycleTray1.Helper.Any(c => c.Status == CellStatus.HasProduct) ||
                   recycleTray2.Helper.Any(c => c.Status == CellStatus.HasProduct))
                {
                    putABBNG(_abbNGTray, 0, $"吸嘴{3 + 0}", 0, recycleTray1);
                    if (!CheckFlowCondition()) return;
                    putABBNG(_abbNGTray, 0, $"吸嘴{3 + 1}", 1, recycleTray1);
                    if (!CheckFlowCondition()) return;
                    putABBNG(_abbNGTray, 1, $"吸嘴{3 + 0}", 0, recycleTray2);
                    if (!CheckFlowCondition()) return;
                    putABBNG(_abbNGTray, 1, $"吸嘴{3 + 1}", 1, recycleTray2);
                    if (!CheckFlowCondition()) return;
                }
                #endregion
                //Golden
                spotCheckStatusLeft = new Dictionary<int, bool[]>();
                spotCheckStatusLeft.Add(0, new bool[SystemConfig.Instance.SpotSNs.GoldenAuditTimes]);
                spotCheckStatusLeft.Add(1, new bool[SystemConfig.Instance.SpotSNs.GoldenAuditTimes]);
                spotCheckStatusLeft.Add(2, new bool[SystemConfig.Instance.SpotSNs.GoldenAuditTimes]);
                spotCheckStatusRight = new Dictionary<int, bool[]>();
                spotCheckStatusRight.Add(0, new bool[SystemConfig.Instance.SpotSNs.GoldenAuditTimes]);
                spotCheckStatusRight.Add(1, new bool[SystemConfig.Instance.SpotSNs.GoldenAuditTimes]);
                spotCheckStatusRight.Add(2, new bool[SystemConfig.Instance.SpotSNs.GoldenAuditTimes]);
                #region 各自取料
                getABBNG(_abbNGTray, 0, $"吸嘴{3 + 0}", 0, recycleTray1, 12);
                if (!CheckFlowCondition()) return;
                getABBNG(_abbNGTray, 0, $"吸嘴{3 + 1}", 1, recycleTray1, 13);
                if (!CheckFlowCondition()) return;

                getABBNG(_abbNGTray, 1, $"吸嘴{3 + 0}", 0, recycleTray2, 14);
                if (!CheckFlowCondition()) return;
                getABBNG(_abbNGTray, 1, $"吸嘴{3 + 1}", 1, recycleTray2, 15);
                if (!CheckFlowCondition()) return;

                SingleAxisMove2Point(_ngAxis, "安全位");
                if (!CheckFlowCondition()) return;
                use1 = false;
                use2 = false;
                if (recycleTray1.Helper.Any(c => c.Status == CellStatus.HasProduct))
                    use1 = true;
                if (recycleTray2.Helper.Any(c => c.Status == CellStatus.HasProduct))
                    use2 = true;
                //先做左边的重复测试，不调换穴位，不调换治具
                PutOK(upReady, recycleTray1, recycleTray2, use1, use2);
                if (!CheckFlowCondition()) return;
                DoPosition(upReady);
                GetOK(upReady, feedTray1, feedTray2, use1, use2);
                if (!CheckFlowCondition()) return;

                #endregion
                #region 各自循环放料
                Task task1a = new Task(() =>
                {
                    if (true)
                    {
                        foreach (var item in spotCheckStatusLeft)
                        {
                            int testerIndex = _isFront ? 0 + item.Key : 6 + item.Key;

                            if (SystemConfig.Instance.UsingStatus.TesterInUseStatus[testerIndex])
                            {
                                //当前治具还有没做完的点检次数
                                for (int i = 0; i < item.Value.Length; i++)
                                {
                                    if (!item.Value[i])
                                    {
                                        (_flowManager.SelectFlow(armLeft) as TransferLogic).GoAndGetPutProduct(item.Key);
                                        if (!CheckFlowCondition()) return;
                                        int h = _isFront ? 0 : 2;
                                        if (recycleTray1.Helper.Any(c => c.Status == CellStatus.HasProduct))
                                        {
                                            TesterLogic testerLogic = _flowManager.SelectFlow($"测试模组{h + 1}{item.Key + 1}") as TesterLogic;
                                            (_flowManager.SelectFlow(armLeft) as TransferLogic).FeedTesterByUnload(item.Key, testerLogic);
                                        }
                                        Thread.Sleep(1000);
                                        (_flowManager.SelectFlow(armLeft) as TransferLogic).WaitTesterFinish(h, item.Key);
                                        if (!CheckFlowCondition()) return;
                                        item.Value[i] = true;
                                        //最后一次了，需要把料取起来
                                        if (i == item.Value.Length - 1)
                                        {
                                            (_flowManager.SelectFlow(armLeft) as TransferLogic).GoAndGetPutProduct(item.Key);
                                        }
                                    }
                                }

                                bool finish = true;
                                foreach (var status in spotCheckStatusLeft)
                                {
                                    int testerIndex2 = _isFront ? 0 + status.Key : 6 + status.Key;

                                    if (SystemConfig.Instance.UsingStatus.TesterInUseStatus[_isFront ? testerIndex2 : testerIndex2 + 6])
                                    {
                                        if (status.Value.Any(c => !c))
                                        {
                                            finish = false;
                                            break;
                                        }
                                    }
                                }

                                if (!finish)
                                {
                                    //做完一个治具后，需要把产品放到精定位再重定位一下
                                    use1 = true;
                                    use2 = false;
                                    PutOKLeft(upReady, recycleTray1);
                                    if (!CheckFlowCondition()) return;
                                    DoPositionLeft(upReady);
                                    GetOKLeft(upReady, feedTray1);
                                    if (!CheckFlowCondition()) return;
                                }
                                else
                                    break;
                            }
                        }
                    }
                    else
                    {
                        int start = 0;
                    retry:
                        DoSpotSingleLeft(spotCheckStatusLeft, start, armLeft, upReady, recycleTray1, recycleTray2, feedTray2, feedTray2);

                        bool finish = true;
                        foreach (var status in spotCheckStatusLeft)
                        {
                            int testerIndex2 = _isFront ? 0 + status.Key : 6 + status.Key;

                            if (SystemConfig.Instance.UsingStatus.TesterInUseStatus[_isFront ? testerIndex2 : testerIndex2 + 6])
                            {
                                if (status.Value.Any(c => !c))
                                {
                                    finish = false;
                                    break;
                                }
                            }
                        }

                        if (!finish)
                        {
                            //做完一个治具后，需要把产品放到精定位再重定位一下
                            use1 = true;
                            use2 = false;
                            PutOKLeft(upReady, recycleTray1);
                            if (!CheckFlowCondition()) return;
                            //DoPosition(upReady);
                            GetOKLeft(upReady, feedTray1);
                            if (!CheckFlowCondition()) return;
                            start++;
                            goto retry;
                        }
                        else
                            return;
                    }
                });
                task1a.Start();
                Task task2b = new Task(() =>
                {
                    if (true)
                    {
                        foreach (var item in spotCheckStatusRight)
                        {
                            int testerIndex = _isFront ? 0 + item.Key + 3 : 6 + item.Key + 3;
                            if (SystemConfig.Instance.UsingStatus.TesterInUseStatus[testerIndex])
                            {
                                //当前治具还有没做完的点检次数
                                for (int i = 0; i < item.Value.Length; i++)
                                {
                                    if (!item.Value[i])
                                    {
                                        (_flowManager.SelectFlow(armRight) as TransferLogic).GoAndGetPutProduct(item.Key);
                                        if (!CheckFlowCondition()) return;
                                        int h = _isFront ? 1 : 3;
                                        if (recycleTray2.Helper.Any(c => c.Status == CellStatus.HasProduct))
                                        {
                                            TesterLogic testerLogic = _flowManager.SelectFlow($"测试模组{h + 1}{item.Key + 1}") as TesterLogic;
                                            (_flowManager.SelectFlow(armRight) as TransferLogic).FeedTesterByUnload(item.Key, testerLogic);
                                        }
                                        (_flowManager.SelectFlow(armRight) as TransferLogic).WaitTesterFinish(h, item.Key);
                                        if (!CheckFlowCondition()) return;
                                        item.Value[i] = true;
                                        //最后一次了，需要把料取起来
                                        if (i == item.Value.Length - 1)
                                        {
                                            (_flowManager.SelectFlow(armRight) as TransferLogic).GoAndGetPutProduct(item.Key);
                                        }
                                    }
                                }


                                bool finish = true;
                                foreach (var status in spotCheckStatusRight)
                                {
                                    int testerIndex2 = _isFront ? 3 + status.Key : 9 + status.Key;

                                    if (SystemConfig.Instance.UsingStatus.TesterInUseStatus[testerIndex2])
                                    {
                                        if (status.Value.Any(c => !c))
                                        {
                                            finish = false;
                                            break;
                                        }
                                    }
                                }

                                if (!finish)
                                {
                                    //做完一个治具后，需要把产品放到精定位再重定位一下
                                    use1 = false;
                                    use2 = true;
                                    PutOKRight(upReady, recycleTray2);
                                    if (!CheckFlowCondition()) return;
                                    DoPositionRight(upReady);
                                    GetOKRight(upReady, feedTray2);
                                    if (!CheckFlowCondition()) return;
                                }
                                else
                                    break;
                            }
                        }
                    }
                    else
                    {
                        int start = 0;
                    retry:
                        DoSpotSingleRight(spotCheckStatusRight, start, armRight, upReady, recycleTray1, recycleTray2, feedTray2, feedTray2);

                        bool finish = true;
                        foreach (var status in spotCheckStatusRight)
                        {
                            int testerIndex2 = _isFront ? 3 + status.Key : 9 + status.Key;

                            if (SystemConfig.Instance.UsingStatus.TesterInUseStatus[testerIndex2])
                            {
                                if (status.Value.Any(c => !c))
                                {
                                    finish = false;
                                    break;
                                }
                            }
                        }

                        if (!finish)
                        {
                            //做完一个治具后，需要把产品放到精定位再重定位一下
                            use1 = false;
                            use2 = true;
                            PutOKRight(upReady, recycleTray2);
                            if (!CheckFlowCondition()) return;
                            //DoPosition(upReady);
                            GetOKRight(upReady, feedTray2);
                            if (!CheckFlowCondition()) return;
                            start++;
                            goto retry;
                        }
                        else
                            return;
                    }
                });
                task2b.Start();
                #endregion
                Task.WaitAll(task1a, task2b);
                #region 放回
                if (recycleTray1.Helper.Any(c => c.Status == CellStatus.HasProduct) ||
                    recycleTray2.Helper.Any(c => c.Status == CellStatus.HasProduct))
                {
                    putABBNG(_abbNGTray, 0, $"吸嘴{3 + 0}", 0, recycleTray1, 11);
                    if (!CheckFlowCondition()) return;
                    putABBNG(_abbNGTray, 0, $"吸嘴{3 + 1}", 1, recycleTray1, 12);
                    if (!CheckFlowCondition()) return;
                    putABBNG(_abbNGTray, 1, $"吸嘴{3 + 0}", 0, recycleTray2, 13);
                    if (!CheckFlowCondition()) return;
                    putABBNG(_abbNGTray, 1, $"吸嘴{3 + 1}", 1, recycleTray2, 14);
                    if (!CheckFlowCondition()) return;
                }
                #endregion

                ShowWarnAndPause("点检完成", "系统", true);
                if (!CheckFlowCondition()) return;
            }
            else
            {
                #region 点检前准备
                _spotCheckTray.Helper.NewFullTray();
                for (int i = 0; i < 4; i++)
                {
                    _spotCheckTray.Helper.SetCellBarcode(i, $"00{i + 1}");
                }
                _abbNGTray.Helper.NewEmptyTray();
                for (int i = 0; i < 12; i++)
                {
                    _abbNGTray.Helper.SetCellStatus(i, CellStatus.HasProduct);
                    _abbNGTray.Helper.SetCellBarcode(i, $"DUMMY-00{i + 1}");
                }
                for (int i = 12; i < 24; i++)
                {
                    _abbNGTray.Helper.SetCellStatus(i, CellStatus.HasProduct);
                    _abbNGTray.Helper.SetCellBarcode(i, _isFront ? SystemConfig.Instance.SpotSNs.SNFront[i - 12] : SystemConfig.Instance.SpotSNs.SNBack[i - 12]);
                }
                #endregion
                #region 确定Arm
                Dictionary<int, bool[]> spotCheckStatusLeft = new Dictionary<int, bool[]>();
                spotCheckStatusLeft.Add(0, new bool[] { false, false, false });
                spotCheckStatusLeft.Add(1, new bool[] { false, false, false });
                spotCheckStatusLeft.Add(2, new bool[] { false, false, false });
                Dictionary<int, bool[]> spotCheckStatusRight = new Dictionary<int, bool[]>();
                spotCheckStatusRight.Add(0, new bool[] { false, false, false });
                spotCheckStatusRight.Add(1, new bool[] { false, false, false });
                spotCheckStatusRight.Add(2, new bool[] { false, false, false });

                Tray recycleTray1 = null;
                Tray recycleTray2 = null;
                Tray feedTray1 = null;
                Tray feedTray2 = null;
                string armLeft = "";
                string armRight = "";
                if (_isFront)
                {
                    recycleTray1 = (_flowManager.SelectFlow("Arm1模组") as TransferLogic).GetRecycleTray();
                    recycleTray2 = (_flowManager.SelectFlow("Arm2模组") as TransferLogic).GetRecycleTray();
                    feedTray1 = (_flowManager.SelectFlow("Arm1模组") as TransferLogic).GetFeedTray();
                    feedTray2 = (_flowManager.SelectFlow("Arm2模组") as TransferLogic).GetFeedTray();

                    armLeft = "Arm1模组";
                    armRight = "Arm2模组";
                }
                else
                {
                    recycleTray1 = (_flowManager.SelectFlow("Arm3模组") as TransferLogic).GetRecycleTray();
                    recycleTray2 = (_flowManager.SelectFlow("Arm4模组") as TransferLogic).GetRecycleTray();
                    feedTray1 = (_flowManager.SelectFlow("Arm3模组") as TransferLogic).GetFeedTray();
                    feedTray2 = (_flowManager.SelectFlow("Arm4模组") as TransferLogic).GetFeedTray();

                    armLeft = "Arm3模组";
                    armRight = "Arm4模组";
                }
                #endregion
                #region 确定当前上下层
                bool upReady = false;
                if (_isFront)
                {
                    upReady = (_flowManager.SelectFlow("精定位移载1") as PrecisionLogic).GetTwoLayerInPositionStatus();
                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"当前上下层状态：{upReady}", this.Description, 0, ""));
                }
                else
                {
                    upReady = (_flowManager.SelectFlow("精定位移载2") as PrecisionLogic).GetTwoLayerInPositionStatus();
                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"当前上下层状态：{upReady}", this.Description, 0, ""));
                }
                #endregion
                //Dummy
                #region 每个治具都上两个dummy
                for (int i = 0; i < 3; i++)
                {
                    //治具启用了
                    if (SystemConfig.Instance.UsingStatus.TesterInUseStatus[i])
                    {
                        getABBNG(_abbNGTray, 0, $"吸嘴{3 + 0}", 0, recycleTray1);
                        if (!CheckFlowCondition()) return;
                        getABBNG(_abbNGTray, 0, $"吸嘴{3 + 1}", 1, recycleTray1);
                        if (!CheckFlowCondition()) return;
                    }
                    if (SystemConfig.Instance.UsingStatus.TesterInUseStatus[i + 3])
                    {
                        getABBNG(_abbNGTray, 1, $"吸嘴{3 + 0}", 0, recycleTray2);
                        if (!CheckFlowCondition()) return;
                        getABBNG(_abbNGTray, 1, $"吸嘴{3 + 1}", 1, recycleTray2);
                        if (!CheckFlowCondition()) return;
                    }

                    SingleAxisMove2Point(_ngAxis, "安全位");
                    if (!CheckFlowCondition()) return;
                    bool use1 = false;
                    bool use2 = false;
                    if (recycleTray1.Helper.Any(c => c.Status == CellStatus.HasProduct))
                        use1 = true;
                    if (recycleTray2.Helper.Any(c => c.Status == CellStatus.HasProduct))
                        use2 = true;
                    if (use1 || use2)
                    {
                        //先做左边的重复测试，不调换穴位，不调换治具
                        PutOK(upReady, recycleTray1, recycleTray2, use1, use2);
                        if (!CheckFlowCondition()) return;
                        DoPosition(upReady);
                        GetOK(upReady, feedTray1, feedTray2, use1, use2);
                        if (!CheckFlowCondition()) return;
                    }

                    //各自放料
                    Task tsk1 = new Task(() =>
                    {
                        //送料到治具
                        if (feedTray1.Helper.Any(c => c.Status == CellStatus.HasProduct))
                        {
                            int idleTester = (_flowManager.SelectFlow(armLeft) as TransferLogic).SelectIdleTester();
                            if (idleTester != -1)
                            {
                                (_flowManager.SelectFlow(armLeft) as TransferLogic).GoAndGetPutProduct(idleTester);
                            }
                        }
                    });
                    tsk1.Start();
                    Task tsk2 = new Task(() =>
                    {
                        //送料到治具
                        if (feedTray2.Helper.Any(c => c.Status == CellStatus.HasProduct))
                        {
                            int idleTester = (_flowManager.SelectFlow(armRight) as TransferLogic).SelectIdleTester();
                            if (idleTester != -1)
                            {
                                (_flowManager.SelectFlow(armRight) as TransferLogic).GoAndGetPutProduct(idleTester);
                            }
                        }
                    });
                    tsk2.Start();
                    //等待各自放料结束
                    Task.WaitAll(tsk1, tsk2);
                }
                #endregion
                #region 重复放料
                Task task1 = new Task(() =>
                {
                    int h = _isFront ? 1 : 3;
                    for (int j = 0; j < SystemConfig.Instance.SpotSNs.DummyAuditTimes - 1; j++)
                    {
                        for (int i = 0; i < 3; i++)
                        {
                            if (SystemConfig.Instance.UsingStatus.TesterInUseStatus[_isFront ? i : i + 6])
                            {
                                (_flowManager.SelectFlow(armLeft) as TransferLogic).WaitTesterFinish(h, i);
                                if (!CheckFlowCondition()) return;
                                (_flowManager.SelectFlow(armLeft) as TransferLogic).GoAndGetPutProduct(i);
                                if (!CheckFlowCondition()) return;
                                if (recycleTray1.Helper.Any(c => c.Status == CellStatus.HasProduct))
                                {
                                    TesterLogic testerLogic = _flowManager.SelectFlow($"测试模组{h}{i + 1}") as TesterLogic;
                                    (_flowManager.SelectFlow(armLeft) as TransferLogic).FeedTesterByUnload(i, testerLogic);
                                }
                            }
                        }
                    }
                });
                task1.Start();
                Task task2 = new Task(() =>
                {
                    int h = _isFront ? 2 : 4;
                    for (int j = 0; j < SystemConfig.Instance.SpotSNs.DummyAuditTimes - 1; j++)
                    {
                        for (int i = 0; i < 3; i++)
                        {
                            if (SystemConfig.Instance.UsingStatus.TesterInUseStatus[_isFront ? i + 3 : i + 9])
                            {
                                (_flowManager.SelectFlow(armRight) as TransferLogic).WaitTesterFinish(h, i);
                                if (!CheckFlowCondition()) return;
                                (_flowManager.SelectFlow(armRight) as TransferLogic).GoAndGetPutProduct(i);
                                if (!CheckFlowCondition()) return;
                                if (recycleTray2.Helper.Any(c => c.Status == CellStatus.HasProduct))
                                {
                                    TesterLogic testerLogic = _flowManager.SelectFlow($"测试模组{h}{i + 1}") as TesterLogic;
                                    (_flowManager.SelectFlow(armRight) as TransferLogic).FeedTesterByUnload(i, testerLogic);
                                }
                            }
                        }
                    }
                });
                task2.Start();
                Task.WaitAll(task1, task2);
            #endregion
            waitget:
                #region 回收dummy
                Task task3 = new Task(() =>
                {
                    //左边取两个测试完成的
                    for (int i = 0; i < 3; i++)
                    {
                        int finishTester = (_flowManager.SelectFlow(armLeft) as TransferLogic).SelectFinishTester();
                        while (finishTester == -1)
                        {
                            finishTester = (_flowManager.SelectFlow(armLeft) as TransferLogic).SelectFinishTester();
                            Thread.Sleep(20);
                        }
                        (_flowManager.SelectFlow(armLeft) as TransferLogic).GoAndGetPutProduct(finishTester);
                        if (recycleTray1.Helper.Any(c => c.Status == CellStatus.HasProduct))
                            break;
                    }
                });
                task3.Start();

                Task task4 = new Task(() =>
                {
                    //右边取两个测试完成的
                    for (int i = 0; i < 3; i++)
                    {
                        int finishTester = (_flowManager.SelectFlow(armRight) as TransferLogic).SelectFinishTester();
                        while (finishTester == -1)
                        {
                            finishTester = (_flowManager.SelectFlow(armRight) as TransferLogic).SelectFinishTester();
                            Thread.Sleep(20);
                        }
                        (_flowManager.SelectFlow(armRight) as TransferLogic).GoAndGetPutProduct(finishTester);
                        if (recycleTray2.Helper.Any(c => c.Status == CellStatus.HasProduct))
                            break;
                    }
                });
                task4.Start();

                Task.WaitAll(task3, task4);

                //两个头只要有一个有料
                if (recycleTray1.Helper.Any(c => c.Status == CellStatus.HasProduct) ||
                    recycleTray2.Helper.Any(c => c.Status == CellStatus.HasProduct))
                {
                    putABBNG(_abbNGTray, 0, $"吸嘴{3 + 0}", 0, recycleTray1);
                    if (!CheckFlowCondition()) return;
                    putABBNG(_abbNGTray, 0, $"吸嘴{3 + 1}", 1, recycleTray1);
                    if (!CheckFlowCondition()) return;

                    putABBNG(_abbNGTray, 1, $"吸嘴{3 + 0}", 0, recycleTray2);
                    if (!CheckFlowCondition()) return;
                    putABBNG(_abbNGTray, 1, $"吸嘴{3 + 1}", 1, recycleTray2);
                    if (!CheckFlowCondition()) return;
                }

                SingleAxisMove2Point(_ngAxis, "安全位");
                if (!CheckFlowCondition()) return;

                //还有料 继续
                if (!CommonMethod.AllTesterNoProduct(_isFront ? 0 : 2))
                {
                    goto waitget;
                }

                #endregion
                //Golden
                #region 每个治具都上两个Golden
                for (int i = 0; i < 3; i++)
                {
                    //治具启用了
                    if (SystemConfig.Instance.UsingStatus.TesterInUseStatus[i])
                    {
                        getABBNG(_abbNGTray, 0, $"吸嘴{3 + 0}", 0, recycleTray1, 12 + i * 2);
                        if (!CheckFlowCondition()) return;
                        getABBNG(_abbNGTray, 0, $"吸嘴{3 + 1}", 1, recycleTray1, 12 + i * 2 + 1);
                        if (!CheckFlowCondition()) return;
                    }
                    if (SystemConfig.Instance.UsingStatus.TesterInUseStatus[i + 3])
                    {
                        getABBNG(_abbNGTray, 1, $"吸嘴{3 + 0}", 0, recycleTray2, 12 + i * 2 + 6);
                        if (!CheckFlowCondition()) return;
                        getABBNG(_abbNGTray, 1, $"吸嘴{3 + 1}", 1, recycleTray2, 12 + i * 2 + 6 + 1);
                        if (!CheckFlowCondition()) return;
                    }

                    SingleAxisMove2Point(_ngAxis, "安全位");
                    if (!CheckFlowCondition()) return;
                    bool use1 = false;
                    bool use2 = false;
                    if (recycleTray1.Helper.Any(c => c.Status == CellStatus.HasProduct))
                        use1 = true;
                    if (recycleTray2.Helper.Any(c => c.Status == CellStatus.HasProduct))
                        use2 = true;
                    if (use1 || use2)
                    {
                        //先做左边的重复测试，不调换穴位，不调换治具
                        PutOK(upReady, recycleTray1, recycleTray2, use1, use2);
                        if (!CheckFlowCondition()) return;
                        DoPosition(upReady);
                        GetOK(upReady, feedTray1, feedTray2, use1, use2);
                        if (!CheckFlowCondition()) return;
                    }

                    //各自放料
                    Task t1 = new Task(() =>
                    {
                        //送料到治具
                        if (feedTray1.Helper.Any(c => c.Status == CellStatus.HasProduct))
                        {
                            int idleTester = (_flowManager.SelectFlow(armLeft) as TransferLogic).SelectIdleTester();
                            if (idleTester != -1)
                            {
                                (_flowManager.SelectFlow(armLeft) as TransferLogic).GoAndGetPutProduct(idleTester);
                            }
                        }
                    });
                    t1.Start();
                    Task t2 = new Task(() =>
                    {
                        //送料到治具
                        if (feedTray2.Helper.Any(c => c.Status == CellStatus.HasProduct))
                        {
                            int idleTester = (_flowManager.SelectFlow(armRight) as TransferLogic).SelectIdleTester();
                            if (idleTester != -1)
                            {
                                (_flowManager.SelectFlow(armRight) as TransferLogic).GoAndGetPutProduct(idleTester);
                            }
                        }
                    });
                    t2.Start();
                    //等待各自放料结束
                    Task.WaitAll(t1, t2);
                }
                #endregion
                #region 重复放料
                Task task1111 = new Task(() =>
                {
                    int h = _isFront ? 1 : 3;
                    for (int j = 0; j < SystemConfig.Instance.SpotSNs.GoldenAuditTimes - 1; j++)
                    {
                        for (int i = 0; i < 3; i++)
                        {
                            if (SystemConfig.Instance.UsingStatus.TesterInUseStatus[_isFront ? i : i + 6])
                            {
                                (_flowManager.SelectFlow(armLeft) as TransferLogic).WaitTesterFinish(h, i);
                                if (!CheckFlowCondition()) return;
                                (_flowManager.SelectFlow(armLeft) as TransferLogic).GoAndGetPutProduct(i);
                                if (!CheckFlowCondition()) return;
                                if (recycleTray1.Helper.Any(c => c.Status == CellStatus.HasProduct))
                                {
                                    TesterLogic testerLogic = _flowManager.SelectFlow($"测试模组{h}{i + 1}") as TesterLogic;
                                    (_flowManager.SelectFlow(armLeft) as TransferLogic).FeedTesterByUnload(i, testerLogic);
                                }
                            }
                        }
                    }
                });
                task1111.Start();
                Task task2222 = new Task(() =>
                {
                    int h = _isFront ? 2 : 4;
                    for (int j = 0; j < SystemConfig.Instance.SpotSNs.GoldenAuditTimes - 1; j++)
                    {
                        for (int i = 0; i < 3; i++)
                        {
                            if (SystemConfig.Instance.UsingStatus.TesterInUseStatus[_isFront ? i + 3 : i + 9])
                            {
                                (_flowManager.SelectFlow(armRight) as TransferLogic).WaitTesterFinish(h, i);
                                if (!CheckFlowCondition()) return;
                                (_flowManager.SelectFlow(armRight) as TransferLogic).GoAndGetPutProduct(i);
                                if (!CheckFlowCondition()) return;
                                if (recycleTray2.Helper.Any(c => c.Status == CellStatus.HasProduct))
                                {
                                    TesterLogic testerLogic = _flowManager.SelectFlow($"测试模组{h}{i + 1}") as TesterLogic;
                                    (_flowManager.SelectFlow(armRight) as TransferLogic).FeedTesterByUnload(i, testerLogic);
                                }
                            }
                        }
                    }
                });
                task2222.Start();
                Task.WaitAll(task1111, task2222);
            #endregion
            waitget2:
                #region 回收Golden
                Task task33 = new Task(() =>
                {
                    //左边取两个测试完成的
                    for (int i = 0; i < 3; i++)
                    {
                        int finishTester = (_flowManager.SelectFlow(armLeft) as TransferLogic).SelectFinishTester();
                        while (finishTester == -1)
                        {
                            finishTester = (_flowManager.SelectFlow(armLeft) as TransferLogic).SelectFinishTester();
                            Thread.Sleep(20);
                        }
                        (_flowManager.SelectFlow(armLeft) as TransferLogic).GoAndGetPutProduct(finishTester);
                        if (recycleTray1.Helper.Any(c => c.Status == CellStatus.HasProduct))
                            break;
                    }
                });
                task33.Start();

                Task task44 = new Task(() =>
                {
                    //右边取两个测试完成的
                    for (int i = 0; i < 3; i++)
                    {
                        int finishTester = (_flowManager.SelectFlow(armRight) as TransferLogic).SelectFinishTester();
                        while (finishTester == -1)
                        {
                            finishTester = (_flowManager.SelectFlow(armRight) as TransferLogic).SelectFinishTester();
                            Thread.Sleep(20);
                        }
                        (_flowManager.SelectFlow(armRight) as TransferLogic).GoAndGetPutProduct(finishTester);
                        if (recycleTray2.Helper.Any(c => c.Status == CellStatus.HasProduct))
                            break;
                    }
                });
                task44.Start();

                Task.WaitAll(task33, task44);

                //两个头只要有一个有料
                if (recycleTray1.Helper.Any(c => c.Status == CellStatus.HasProduct) ||
                    recycleTray2.Helper.Any(c => c.Status == CellStatus.HasProduct))
                {
                    if (recycleTray1.Helper.Any(c => c.Status == CellStatus.HasProduct))
                    {
                        putABBNG(_abbNGTray, 0, $"吸嘴{3 + 0}", 0, recycleTray1, 12 + (recycleTray1.Helper.GetCell(0).TestedTesters.Last()) * 2);
                        if (!CheckFlowCondition()) return;
                        putABBNG(_abbNGTray, 0, $"吸嘴{3 + 1}", 1, recycleTray1, 12 + (recycleTray1.Helper.GetCell(0).TestedTesters.Last()) * 2 + 1);
                        if (!CheckFlowCondition()) return;
                    }

                    if (recycleTray2.Helper.Any(c => c.Status == CellStatus.HasProduct))
                    {
                        putABBNG(_abbNGTray, 1, $"吸嘴{3 + 0}", 0, recycleTray2, 12 + (recycleTray2.Helper.GetCell(0).TestedTesters.Last()) * 2);
                        if (!CheckFlowCondition()) return;
                        putABBNG(_abbNGTray, 1, $"吸嘴{3 + 1}", 1, recycleTray2, 12 + (recycleTray2.Helper.GetCell(0).TestedTesters.Last()) * 2 + 1);
                        if (!CheckFlowCondition()) return;
                    }
                }

                SingleAxisMove2Point(_ngAxis, "安全位");
                if (!CheckFlowCondition()) return;

                //还有料 继续
                if (!CommonMethod.AllTesterNoProduct(_isFront ? 0 : 2))
                {
                    goto waitget2;
                }

                #endregion

                ShowWarnAndPause("点检结束!", "系统", true);
            }
        }
        public void DoSpotSingleRight(Dictionary<int, bool[]> spotCheckStatus, int index, string armName, bool upReady, Tray recycleTray1, Tray recycleTray2, Tray feedTray1, Tray feedTray2)
        {
            int testerIndex = _isFront ? 0 + index + 3 : 6 + index + 3;
            if (SystemConfig.Instance.UsingStatus.TesterInUseStatus[testerIndex])
            {
                //当前治具还有没做完的点检次数
                for (int i = 0; i < spotCheckStatus[index].Length; i++)
                {
                    if (!spotCheckStatus[index][i])
                    {
                        (_flowManager.SelectFlow(armName) as TransferLogic).GoAndGetPutProduct(index);
                        if (!CheckFlowCondition()) return;
                        int h = _isFront ? 1 : 3;
                        if (recycleTray2.Helper.Any(c => c.Status == CellStatus.HasProduct))
                        {
                            TesterLogic testerLogic = _flowManager.SelectFlow($"测试模组{h + 1}{index + 1}") as TesterLogic;
                            (_flowManager.SelectFlow(armName) as TransferLogic).FeedTesterByUnload(index, testerLogic);
                        }
                        (_flowManager.SelectFlow(armName) as TransferLogic).WaitTesterFinish(h, index);
                        if (!CheckFlowCondition()) return;
                        spotCheckStatus[index][i] = true;
                        //最后一次了，需要把料取起来
                        if (i == spotCheckStatus[index].Length - 1)
                        {
                            (_flowManager.SelectFlow(armName) as TransferLogic).GoAndGetPutProduct(index);
                        }
                    }
                }
            }
        }
        public void DoSpotSingleLeft(Dictionary<int, bool[]> spotCheckStatus, int index, string armName, bool upReady, Tray recycleTray1, Tray recycleTray2, Tray feedTray1, Tray feedTray2)
        {
            int testerIndex = _isFront ? 0 + index : 6 + index;

            if (SystemConfig.Instance.UsingStatus.TesterInUseStatus[testerIndex])
            {
                //当前治具还有没做完的点检次数
                for (int i = 0; i < spotCheckStatus[index].Length; i++)
                {
                    if (!spotCheckStatus[index][i])
                    {
                        (_flowManager.SelectFlow(armName) as TransferLogic).GoAndGetPutProduct(index);
                        if (!CheckFlowCondition()) return;
                        int h = _isFront ? 0 : 2;
                        if (recycleTray1.Helper.Any(c => c.Status == CellStatus.HasProduct))
                        {
                            TesterLogic testerLogic = _flowManager.SelectFlow($"测试模组{h + 1}{index + 1}") as TesterLogic;
                            (_flowManager.SelectFlow(armName) as TransferLogic).FeedTesterByUnload(index, testerLogic);
                        }
                        Thread.Sleep(1000);
                        (_flowManager.SelectFlow(armName) as TransferLogic).WaitTesterFinish(h, index);
                        if (!CheckFlowCondition()) return;
                        spotCheckStatus[index][i] = true;
                        //最后一次了，需要把料取起来
                        if (i == spotCheckStatus[index].Length - 1)
                        {
                            (_flowManager.SelectFlow(armName) as TransferLogic).GoAndGetPutProduct(index);
                        }
                    }
                }
            }
        }
        public override void OnStop()
        {
            base.OnStop();
        }
        public override bool PreStartCheck()
        {
            return base.PreStartCheck();
        }
        public void DoPosition(bool upReady)
        {
            //if (_isFront)
            //{
            //    if (upReady)
            //    {
            //        //if(_isFront)
            //        //    _precisionUpRecycleVacs1.ForEach(v => v.Off());
            //        //else
            //        _precisionUpRecycleVacs2.ForEach(v => v.Off());
            //        _precisionUpRecycleVacs1.ForEach(v => v.Off());
            //        MultiCylinderOperate(new List<Cylinder>() { _upPositionCylinder1, _upPositionCylinder2 }, 5000, new List<bool>() { true, true });
            //        if (!CheckFlowCondition()) return;
            //        Thread.Sleep(200);
            //        MultiCylinderOperate(new List<Cylinder>() { _upPositionCylinder1, _upPositionCylinder2 }, 5000, new List<bool>() { false, false });
            //        if (!CheckFlowCondition()) return;
            //        Thread.Sleep(200);
            //        _precisionUpRecycleVacs2.ForEach(v => v.On());
            //        _precisionUpRecycleVacs1.ForEach(v => v.On());
            //    }
            //    else
            //    {
            //        _precisionDownRecycleVacs2.ForEach(v => v.Off());
            //        _precisionDownRecycleVacs1.ForEach(v => v.Off());

            //        MultiCylinderOperate(new List<Cylinder>() { _downPositionCylinder1, _downPositionCylinder2 }, 5000, new List<bool>() { true, true });
            //        if (!CheckFlowCondition()) return;
            //        Thread.Sleep(200);
            //        MultiCylinderOperate(new List<Cylinder>() { _downPositionCylinder1, _downPositionCylinder2 }, 5000, new List<bool>() { false, false });
            //        if (!CheckFlowCondition()) return;
            //        Thread.Sleep(200);
            //        _precisionDownRecycleVacs2.ForEach(v => v.On());
            //        _precisionDownRecycleVacs1.ForEach(v => v.On());
            //    }
            //}
            //else
            {
                if (upReady)
                {
                    //if(_isFront)
                    //    _precisionUpRecycleVacs1.ForEach(v => v.Off());
                    //else
                    //_precisionUpRecycleVacs2.ForEach(v => v.Off());
                    //_precisionUpRecycleVacs1.ForEach(v => v.Off());
                    MultiCylinderOperate(_upRecyclePositionCylinder, 5000, new List<bool>() { true, true });
                    if (!CheckFlowCondition()) return;
                    Thread.Sleep(200);
                    MultiCylinderOperate(_upRecyclePositionCylinder, 5000, new List<bool>() { false, false });
                    if (!CheckFlowCondition()) return;
                    Thread.Sleep(200);
                    //_precisionUpRecycleVacs2.ForEach(v => v.On());
                    //_precisionUpRecycleVacs1.ForEach(v => v.On());
                }
                else
                {
                    //_precisionDownRecycleVacs2.ForEach(v => v.Off());
                    //_precisionDownRecycleVacs1.ForEach(v => v.Off());

                    MultiCylinderOperate(_downRecyclePositionCylinder, 5000, new List<bool>() { true, true });
                    if (!CheckFlowCondition()) return;
                    Thread.Sleep(200);
                    MultiCylinderOperate(_downRecyclePositionCylinder, 5000, new List<bool>() { false, false });
                    if (!CheckFlowCondition()) return;
                    Thread.Sleep(200);
                    //_precisionDownRecycleVacs2.ForEach(v => v.On());
                    //_precisionDownRecycleVacs1.ForEach(v => v.On());
                }
            }
        }
        public void DoPositionLeft(bool upReady)
        {
            //if (_isFront)
            //{
            //    if (upReady)
            //    {
            //        //if(_isFront)
            //        //    _precisionUpRecycleVacs1.ForEach(v => v.Off());
            //        //else
            //        _precisionUpRecycleVacs1.ForEach(v => v.Off());
            //        MultiCylinderOperate(new List<Cylinder>() { _upPositionCylinder2 }, 5000, new List<bool>() { true });
            //        if (!CheckFlowCondition()) return;
            //        Thread.Sleep(200);
            //        MultiCylinderOperate(new List<Cylinder>() { _upPositionCylinder2 }, 5000, new List<bool>() { false });
            //        if (!CheckFlowCondition()) return;
            //        Thread.Sleep(200);
            //        _precisionUpRecycleVacs1.ForEach(v => v.On());
            //    }
            //    else
            //    {
            //        _precisionDownRecycleVacs1.ForEach(v => v.Off());

            //        MultiCylinderOperate(new List<Cylinder>() { _downPositionCylinder2 }, 5000, new List<bool>() { true });
            //        if (!CheckFlowCondition()) return;
            //        Thread.Sleep(200);
            //        MultiCylinderOperate(new List<Cylinder>() { _downPositionCylinder2 }, 5000, new List<bool>() { false });
            //        if (!CheckFlowCondition()) return;
            //        Thread.Sleep(200);
            //        _precisionDownRecycleVacs1.ForEach(v => v.On());
            //    }
            //}
            //else
            {
                if (upReady)
                {
                    //if(_isFront)
                    //    _precisionUpRecycleVacs1.ForEach(v => v.Off());
                    //else
                    //_precisionUpRecycleVacs1.ForEach(v => v.Off());
                    SingleCylinderOperate(_upRecyclePositionCylinder[1], 5000, true);
                    if (!CheckFlowCondition()) return;
                    Thread.Sleep(200);
                    SingleCylinderOperate(_upRecyclePositionCylinder[1], 5000, false);
                    if (!CheckFlowCondition()) return;
                    Thread.Sleep(200);
                    //_precisionUpRecycleVacs1.ForEach(v => v.On());
                }
                else
                {
                    //_precisionDownRecycleVacs1.ForEach(v => v.Off());
                    SingleCylinderOperate(_downRecyclePositionCylinder[1], 5000, true);
                    if (!CheckFlowCondition()) return;
                    Thread.Sleep(200);
                    SingleCylinderOperate(_downRecyclePositionCylinder[1], 5000, false);
                    if (!CheckFlowCondition()) return;
                    Thread.Sleep(200);
                    //_precisionDownRecycleVacs1.ForEach(v => v.On());
                }
            }
        }
        public void DoPositionRight(bool upReady)
        {
            //if (_isFront)
            //{
            //    if (upReady)
            //    {
            //        //if(_isFront)
            //        //    _precisionUpRecycleVacs1.ForEach(v => v.Off());
            //        //else
            //        _precisionUpRecycleVacs2.ForEach(v => v.Off());
            //        MultiCylinderOperate(new List<Cylinder>() { _upPositionCylinder1 }, 5000, new List<bool>() { true });
            //        if (!CheckFlowCondition()) return;
            //        Thread.Sleep(200);
            //        MultiCylinderOperate(new List<Cylinder>() { _upPositionCylinder1 }, 5000, new List<bool>() { false });
            //        if (!CheckFlowCondition()) return;
            //        Thread.Sleep(200);
            //        _precisionUpRecycleVacs2.ForEach(v => v.On());
            //    }
            //    else
            //    {
            //        _precisionDownRecycleVacs2.ForEach(v => v.Off());

            //        MultiCylinderOperate(new List<Cylinder>() { _downPositionCylinder1 }, 5000, new List<bool>() { true });
            //        if (!CheckFlowCondition()) return;
            //        Thread.Sleep(200);
            //        MultiCylinderOperate(new List<Cylinder>() { _downPositionCylinder1 }, 5000, new List<bool>() { false });
            //        if (!CheckFlowCondition()) return;
            //        Thread.Sleep(200);
            //        _precisionDownRecycleVacs2.ForEach(v => v.On());
            //    }
            //}
            //else
            {
                if (upReady)
                {
                    //if(_isFront)
                    //    _precisionUpRecycleVacs1.ForEach(v => v.Off());
                    //else
                    //_precisionUpRecycleVacs2.ForEach(v => v.Off());
                    SingleCylinderOperate(_upRecyclePositionCylinder[0], 5000, true);
                    if (!CheckFlowCondition()) return;
                    Thread.Sleep(200);
                    SingleCylinderOperate(_upRecyclePositionCylinder[0], 5000, false);
                    if (!CheckFlowCondition()) return;
                    Thread.Sleep(200);
                    //_precisionUpRecycleVacs2.ForEach(v => v.On());
                }
                else
                {
                    //_precisionDownRecycleVacs2.ForEach(v => v.Off());

                    SingleCylinderOperate(_downRecyclePositionCylinder[0], 5000, false);
                    if (!CheckFlowCondition()) return;
                    Thread.Sleep(200);
                    SingleCylinderOperate(_downRecyclePositionCylinder[0], 5000, false);
                    if (!CheckFlowCondition()) return;
                    Thread.Sleep(200);
                    //_precisionDownRecycleVacs2.ForEach(v => v.On());
                }
            }
        }
        public void DoPosition2(bool upReady)
        {
            //if (_isFront)
            //{
            //    if (upReady)
            //    {
            //        if (_isFront)
            //            _precisionUpRecycleVacs1.ForEach(v => v.Off());
            //        else
            //            _precisionUpRecycleVacs2.ForEach(v => v.Off());
            //        MultiCylinderOperate(new List<Cylinder>() { _upPositionCylinder1, _upPositionCylinder2 }, 5000, new List<bool>() { true, true });
            //        if (!CheckFlowCondition()) return;
            //        Thread.Sleep(200);
            //        MultiCylinderOperate(new List<Cylinder>() { _upPositionCylinder1, _upPositionCylinder2 }, 5000, new List<bool>() { false, false });
            //        if (!CheckFlowCondition()) return;
            //        Thread.Sleep(200);
            //        if (_isFront)
            //            _precisionUpRecycleVacs1.ForEach(v => v.On());
            //        else
            //            _precisionUpRecycleVacs2.ForEach(v => v.On());
            //    }
            //    else
            //    {
            //        if (_isFront)
            //            _precisionDownRecycleVacs1.ForEach(v => v.Off());
            //        else
            //            _precisionDownRecycleVacs2.ForEach(v => v.Off());

            //        MultiCylinderOperate(new List<Cylinder>() { _downPositionCylinder1, _downPositionCylinder2 }, 5000, new List<bool>() { true, true });
            //        if (!CheckFlowCondition()) return;
            //        Thread.Sleep(200);
            //        MultiCylinderOperate(new List<Cylinder>() { _downPositionCylinder1, _downPositionCylinder2 }, 5000, new List<bool>() { false, false });
            //        if (!CheckFlowCondition()) return;
            //        Thread.Sleep(200);
            //        if (_isFront)
            //            _precisionDownRecycleVacs1.ForEach(v => v.On());
            //        else
            //            _precisionDownRecycleVacs2.ForEach(v => v.On());
            //    }
            //}
            //else
            {
                if (upReady)
                {
                    //if (_isFront)
                    //    _precisionUpRecycleVacs1.ForEach(v => v.Off());
                    //else
                    //    _precisionUpRecycleVacs2.ForEach(v => v.Off());
                    MultiCylinderOperate(_upRecyclePositionCylinder, 5000, new List<bool>() { true, true });
                    if (!CheckFlowCondition()) return;
                    Thread.Sleep(200);
                    MultiCylinderOperate(_upRecyclePositionCylinder, 5000, new List<bool>() { false, false });
                    if (!CheckFlowCondition()) return;
                    Thread.Sleep(200);
                    //if (_isFront)
                    //    _precisionUpRecycleVacs1.ForEach(v => v.On());
                    //else
                    //    _precisionUpRecycleVacs2.ForEach(v => v.On());
                }
                else
                {
                    //if (_isFront)
                    //    _precisionDownRecycleVacs1.ForEach(v => v.Off());
                    //else
                    //    _precisionDownRecycleVacs2.ForEach(v => v.Off());

                    MultiCylinderOperate(_downRecyclePositionCylinder, 5000, new List<bool>() { true, true });
                    if (!CheckFlowCondition()) return;
                    Thread.Sleep(200);
                    MultiCylinderOperate(_downRecyclePositionCylinder, 5000, new List<bool>() { false, false });
                    if (!CheckFlowCondition()) return;
                    Thread.Sleep(200);
                    //if (_isFront)
                    //    _precisionDownRecycleVacs1.ForEach(v => v.On());
                    //else
                    //    _precisionDownRecycleVacs2.ForEach(v => v.On());
                }
            }
        }
        public void PutOK(bool upReady, Tray recycleTray1, Tray recycleTray2, bool use1 = true, bool use2 = true)
        {
            string upPos = upReady ? "放上层OK料后抬升位" : "放下层OK料后抬升位";
            AxisMoveSimultaneously(new List<Axis>() { _z1, _z2 }, "待机位");
            if (!CheckFlowCondition()) return;
            safetyCheck(upReady);
            if (!CheckFlowCondition()) return;
            Task t1 = null;
            Task t2 = null;
            if (use1)
            {
                t1 = Task.Run(() =>
                {
                    Cylinder _changeCylinder = MachineResource.Instance.MachineCylinder[$"Arm1变距气缸"];
                    string putPosPrepare = "";
                    string putPos = "";
                    int headerIndex = 0;
                    if (_isFront)
                    {
                        putPos = upReady ? $"Arm1精定位上层放料位置" : $"Arm1精定位下层放料位置";
                        putPosPrepare = upReady ? "Arm1精定位上层放料位置预备" : "Arm1精定位下层放料位置预备";
                        _changeCylinder = MachineResource.Instance.MachineCylinder[$"Arm1变距气缸"];
                        headerIndex = 0;
                    }
                    else
                    {
                        putPos = upReady ? $"Arm3精定位上层放料位置" : $"Arm3精定位下层放料位置";
                        putPosPrepare = upReady ? "Arm3精定位上层放料位置预备" : "Arm3精定位下层放料位置预备";
                        _changeCylinder = MachineResource.Instance.MachineCylinder[$"Arm3变距气缸"];
                        headerIndex = 2;
                    }
                    SingleAxisMove2Point(_y1, "旋转位");
                    if (!CheckFlowCondition()) return;
                    AxisMoveSimultaneously(new List<Axis>() { _x1, _r1 }, putPosPrepare);
                    if (!CheckFlowCondition()) return;
                    SingleAxisMove2Point(_y1, putPosPrepare);
                    if (!CheckFlowCondition()) return;
                    List<bool> productStatus = new List<bool>();
                    productStatus = recycleTray1.Helper.Select(c => c.Status == CellStatus.HasProduct).ToList();
                    //string zPos = "";
                    string precisionName = "";
                    if (_isFront)
                    {
                        //zPos = upReady ? "Arm1精定位上层放料高度" : "Arm1精定位下层放料高度";
                        precisionName = "精定位移载1";
                    }
                    else
                    {
                        //zPos = upReady ? "Arm3精定位上层放料高度" : "Arm3精定位下层放料高度";
                        precisionName = "精定位移载2";
                    }
                    //if (_isFront)
                    //{
                    //    NozzlePutProductExtDoE2(_z1,
                    //                    _recycleCylinders1,
                    //                    _recycleVacs1,
                    //                    _recycleRevVacs1,
                    //                    upReady ? _precisionUpRecycleVacs1 : _precisionDownRecycleVacs1,
                    //                    upReady ? _upPositionCylinder1 : _downPositionCylinder1,
                    //                    checkChangeCylinder: _changeCylinder,
                    //                    _x1,
                    //                    _y1,
                    //                    putPos,
                    //                    putPosPrepare,
                    //                    _z1.MotionPosition[upPos],
                    //                    zPutRelPos: SystemConfig.Instance.TestParam.ArmZHValuePutInPrecision,
                    //                    zPutRelPosSpeed: SystemConfig.Instance.TestParam.ArmZHValueSpeedPutInPrecision,
                    //                    _isFront ? SystemConfig.Instance.ArmPutPrecisionParam[0].NozzleTimeOut : SystemConfig.Instance.ArmPutPrecisionParam[2].NozzleTimeOut,
                    //                    _isFront ? SystemConfig.Instance.ArmPutPrecisionParam[0].DelayBeforeNozzleUp : SystemConfig.Instance.ArmPutPrecisionParam[2].DelayBeforeNozzleUp,
                    //                    productStatus,
                    //                    clampDelayCylinderAfter: upReady ? SystemConfig.Instance.UsingStatus.ClampPrecisionDelayInArmUp : SystemConfig.Instance.UsingStatus.ClampPrecisionDelayInArmDown,
                    //                    clampDelayCylinderBefore: upReady ? SystemConfig.Instance.UsingStatus.ClampPrecisionDelayBeforeInArmUp : SystemConfig.Instance.UsingStatus.ClampPrecisionDelayBeforeInArmDown,
                    //                    headerIndex: headerIndex);
                    //}
                    //else
                    //{
                        NozzlePutProductExtDoE2(_z1,
                                          _recycleCylinders1,
                                          _recycleVacs1,
                                          _recycleRevVacs1,
                                          vacOther:null,
                                          upReady ? _upRecyclePositionCylinder[1] : _downRecyclePositionCylinder[1],
                                          checkChangeCylinder: _changeCylinder,
                                          _x1,
                                          _y1,
                                          putPos,
                                          putPosPrepare,
                                          _z1.MotionPosition[upPos],
                                          zPutRelPos: SystemConfig.Instance.TestParam.ArmZHValuePutInPrecision,
                                          zPutRelPosSpeed: SystemConfig.Instance.TestParam.ArmZHValueSpeedPutInPrecision,
                                          _isFront ? SystemConfig.Instance.ArmPutPrecisionParam[0].NozzleTimeOut : SystemConfig.Instance.ArmPutPrecisionParam[2].NozzleTimeOut,
                                          _isFront ? SystemConfig.Instance.ArmPutPrecisionParam[0].DelayBeforeNozzleUp : SystemConfig.Instance.ArmPutPrecisionParam[2].DelayBeforeNozzleUp,
                                          productStatus,
                                          clampDelayCylinderAfter: upReady ? SystemConfig.Instance.UsingStatus.ClampPrecisionDelayInArmUp : SystemConfig.Instance.UsingStatus.ClampPrecisionDelayInArmDown,
                                          clampDelayCylinderBefore: upReady ? SystemConfig.Instance.UsingStatus.ClampPrecisionDelayBeforeInArmUp : SystemConfig.Instance.UsingStatus.ClampPrecisionDelayBeforeInArmDown,
                                          headerIndex: headerIndex);
                    //}
                    if (!CheckFlowCondition()) return;
                    //交换料状态
                    //productStatus.Reverse();
                    Tray precisionRecycleTray = upReady ? (_flowManager.SelectFlow(precisionName) as PrecisionLogic).GetRecycleTray1Up() : (_flowManager.SelectFlow(precisionName) as PrecisionLogic).GetRecycleTray1Down();
                    for (int i = 0; i < productStatus.Count; i++)
                    {
                        if (productStatus[i])
                        {
                            if (i == 0)
                            {
                                precisionRecycleTray.Helper.SetCellStatus(1, recycleTray1.Helper.GetCell(0).Status);
                                precisionRecycleTray.Helper.SetCellBarcode(1, recycleTray1.Helper.GetCell(0).SN);
                                precisionRecycleTray.Helper.SetCellResult(1, recycleTray1.Helper.GetCell(0).Result);
                                precisionRecycleTray.Helper.SetCellTesters(1, recycleTray1.Helper.GetCell(0).TestedTesters);

                                recycleTray1.Helper.SetCellStatus(0, CellStatus.NoProduct);
                                recycleTray1.Helper.SetCellBarcode(0, string.Empty);
                                recycleTray1.Helper.SetCellResult(0, TestResult.NoTest);
                            }
                            else
                            {
                                precisionRecycleTray.Helper.SetCellStatus(0, recycleTray1.Helper.GetCell(1).Status);
                                precisionRecycleTray.Helper.SetCellBarcode(0, recycleTray1.Helper.GetCell(1).SN);
                                precisionRecycleTray.Helper.SetCellResult(0, recycleTray1.Helper.GetCell(1).Result);
                                precisionRecycleTray.Helper.SetCellTesters(0, recycleTray1.Helper.GetCell(1).TestedTesters);

                                recycleTray1.Helper.SetCellStatus(1, CellStatus.NoProduct);
                                recycleTray1.Helper.SetCellBarcode(1, string.Empty);
                                recycleTray1.Helper.SetCellResult(1, TestResult.NoTest);
                            }
                        }
                    }
                });
            }
            if (use2)
            {
                t2 = Task.Run(() =>
                {
                    Cylinder _changeCylinder = MachineResource.Instance.MachineCylinder[$"Arm2变距气缸"];
                    string putPosPrepare = "";
                    string putPos = "";
                    int headerIndex = 0;
                    if (_isFront)
                    {
                        putPos = upReady ? $"Arm2精定位上层放料位置" : $"Arm2精定位下层放料位置";
                        putPosPrepare = upReady ? $"Arm2精定位上层放料位置预备" : $"Arm2精定位下层放料位置预备";
                        _changeCylinder = MachineResource.Instance.MachineCylinder[$"Arm2变距气缸"];
                        headerIndex = 1;
                    }
                    else
                    {
                        putPos = upReady ? $"Arm4精定位上层放料位置" : $"Arm4精定位下层放料位置";
                        putPosPrepare = upReady ? $"Arm4精定位上层放料位置预备" : $"Arm4精定位下层放料位置预备";
                        _changeCylinder = MachineResource.Instance.MachineCylinder[$"Arm4变距气缸"];
                        headerIndex = 3;
                    }
                    SingleAxisMove2Point(_y2, "旋转位");
                    if (!CheckFlowCondition()) return;
                    AxisMoveSimultaneously(new List<Axis>() { _x2, _r2 }, putPosPrepare);
                    if (!CheckFlowCondition()) return;
                    SingleAxisMove2Point(_y2, putPosPrepare);
                    if (!CheckFlowCondition()) return;

                    List<bool> productStatus = new List<bool>();
                    //if (_isFront)
                    //    productStatus = recycleTray2.Helper.Select(c => c.Status == CellStatus.HasProduct).Reverse().ToList();
                    //else
                    productStatus = recycleTray2.Helper.Select(c => c.Status == CellStatus.HasProduct).ToList();
                    //string zPos = "";
                    string precisionName = "";
                    if (_isFront)
                    {
                        //zPos = upReady ? "Arm2精定位上层放料高度" : "Arm2精定位下层放料高度";
                        precisionName = "精定位移载1";
                    }
                    else
                    {
                        //zPos = upReady ? "Arm4精定位上层放料高度" : "Arm4精定位下层放料高度";
                        precisionName = "精定位移载2";
                    }
                    //if (_isFront)
                    //{
                    //    NozzlePutProductExtDoE2(_z2,
                    //                  _recycleCylinders2,
                    //                  _recycleVacs2,
                    //                  _recycleRevVacs2,
                    //                  upReady ? _precisionUpRecycleVacs2 : _precisionDownRecycleVacs2,
                    //                  upReady ? _upPositionCylinder2 : _downPositionCylinder2,
                    //                  checkChangeCylinder: _changeCylinder,
                    //                  _x2,
                    //                  _y2,
                    //                  putPos,
                    //                  putPosPrepare,
                    //                  _z2.MotionPosition[upPos],
                    //                  zPutRelPos: SystemConfig.Instance.TestParam.ArmZHValuePutInPrecision,
                    //                  zPutRelPosSpeed: SystemConfig.Instance.TestParam.ArmZHValueSpeedPutInPrecision,
                    //                  _isFront ? SystemConfig.Instance.ArmPutPrecisionParam[1].NozzleTimeOut : SystemConfig.Instance.ArmPutPrecisionParam[3].NozzleTimeOut,
                    //                  _isFront ? SystemConfig.Instance.ArmPutPrecisionParam[1].DelayBeforeNozzleUp : SystemConfig.Instance.ArmPutPrecisionParam[3].DelayBeforeNozzleUp,
                    //                  productStatus,
                    //                  clampDelayCylinderAfter: upReady ? SystemConfig.Instance.UsingStatus.ClampPrecisionDelayInArmUp : SystemConfig.Instance.UsingStatus.ClampPrecisionDelayInArmDown,
                    //                  clampDelayCylinderBefore: upReady ? SystemConfig.Instance.UsingStatus.ClampPrecisionDelayBeforeInArmUp : SystemConfig.Instance.UsingStatus.ClampPrecisionDelayBeforeInArmDown,
                    //                  headerIndex: headerIndex);
                    //}
                    //else
                    {
                        NozzlePutProductExtDoE2(_z2,
                                      _recycleCylinders2,
                                      _recycleVacs2,
                                      _recycleRevVacs2,
                                      vacOther: null,
                                      upReady ? _upRecyclePositionCylinder[0] : _downRecyclePositionCylinder[0],
                                      checkChangeCylinder: _changeCylinder,
                                      _x2,
                                      _y2,
                                      putPos,
                                      putPosPrepare,
                                      _z2.MotionPosition[upPos],
                                      zPutRelPos: SystemConfig.Instance.TestParam.ArmZHValuePutInPrecision,
                                      zPutRelPosSpeed: SystemConfig.Instance.TestParam.ArmZHValueSpeedPutInPrecision,
                                      _isFront ? SystemConfig.Instance.ArmPutPrecisionParam[1].NozzleTimeOut : SystemConfig.Instance.ArmPutPrecisionParam[3].NozzleTimeOut,
                                      _isFront ? SystemConfig.Instance.ArmPutPrecisionParam[1].DelayBeforeNozzleUp : SystemConfig.Instance.ArmPutPrecisionParam[3].DelayBeforeNozzleUp,
                                      productStatus,
                                      clampDelayCylinderAfter: upReady ? SystemConfig.Instance.UsingStatus.ClampPrecisionDelayInArmUp : SystemConfig.Instance.UsingStatus.ClampPrecisionDelayInArmDown,
                                      clampDelayCylinderBefore: upReady ? SystemConfig.Instance.UsingStatus.ClampPrecisionDelayBeforeInArmUp : SystemConfig.Instance.UsingStatus.ClampPrecisionDelayBeforeInArmDown,
                                      headerIndex: headerIndex);
                    }
                    if (!CheckFlowCondition()) return;
                    string pointName = "";
                    if (_isFront)
                    {
                        pointName = upReady ? "Arm2精定位上层取料位置" : "Arm2精定位下层取料位置";
                    }
                    else
                    {
                        pointName = upReady ? "Arm4精定位上层取料位置" : "Arm4精定位下层取料位置";
                    }
                    SingleAxisMove2Point(_x2, pointName);
                    if (!CheckFlowCondition()) return;
                    //交换料状态
                    //if (_isFront)
                    //    productStatus.Reverse();
                    Tray precisionRecycleTray = upReady ? (_flowManager.SelectFlow(precisionName) as PrecisionLogic).GetRecycleTray2Up() : (_flowManager.SelectFlow(precisionName) as PrecisionLogic).GetRecycleTray2Down();
                    for (int i = 0; i < productStatus.Count; i++)
                    {
                        if (_isFront)
                        {
                            if (productStatus[i])
                            {
                                if (i == 0)
                                {
                                    precisionRecycleTray.Helper.SetCellStatus(1, recycleTray2.Helper.GetCell(0).Status);
                                    precisionRecycleTray.Helper.SetCellBarcode(1, recycleTray2.Helper.GetCell(0).SN);
                                    precisionRecycleTray.Helper.SetCellResult(1, recycleTray2.Helper.GetCell(0).Result);
                                    precisionRecycleTray.Helper.SetCellTesters(1, recycleTray2.Helper.GetCell(0).TestedTesters);

                                    recycleTray2.Helper.SetCellStatus(0, CellStatus.NoProduct);
                                    recycleTray2.Helper.SetCellBarcode(0, string.Empty);
                                    recycleTray2.Helper.SetCellResult(0, TestResult.NoTest);
                                }
                                else
                                {
                                    precisionRecycleTray.Helper.SetCellStatus(0, recycleTray2.Helper.GetCell(1).Status);
                                    precisionRecycleTray.Helper.SetCellBarcode(0, recycleTray2.Helper.GetCell(1).SN);
                                    precisionRecycleTray.Helper.SetCellResult(0, recycleTray2.Helper.GetCell(1).Result);
                                    precisionRecycleTray.Helper.SetCellTesters(0, recycleTray2.Helper.GetCell(1).TestedTesters);

                                    recycleTray2.Helper.SetCellStatus(1, CellStatus.NoProduct);
                                    recycleTray2.Helper.SetCellBarcode(1, string.Empty);
                                    recycleTray2.Helper.SetCellResult(1, TestResult.NoTest);
                                }
                            }
                        }
                        else
                        {
                            if (productStatus[i])
                            {
                                precisionRecycleTray.Helper.SetCellStatus(i, recycleTray2.Helper.GetCell(i).Status);
                                precisionRecycleTray.Helper.SetCellBarcode(i, recycleTray2.Helper.GetCell(i).SN);
                                precisionRecycleTray.Helper.SetCellResult(i, recycleTray2.Helper.GetCell(i).Result);
                                precisionRecycleTray.Helper.SetCellTesters(i, recycleTray2.Helper.GetCell(i).TestedTesters);

                                recycleTray2.Helper.SetCellStatus(i, CellStatus.NoProduct);
                                recycleTray2.Helper.SetCellBarcode(i, string.Empty);
                                recycleTray2.Helper.SetCellResult(i, TestResult.NoTest);
                            }
                        }
                    }
                });
            }
            if (use1 && use2)
                Task.WaitAll(t1, t2);
            else if (use1)
                Task.WaitAll(t1);
            else if (use2)
                Task.WaitAll(t2);
            if (!CheckFlowCondition()) return;
        }
        public void PutOK2(bool upReady, Tray feedTray1, Tray feedTray2, bool use1 = true, bool use2 = true)
        {
            string upPos = upReady ? "放上层OK料后抬升位" : "放下层OK料后抬升位";
            AxisMoveSimultaneously(new List<Axis>() { _z1, _z2 }, "待机位");
            if (!CheckFlowCondition()) return;

            safetyCheck(upReady);
            if (!CheckFlowCondition()) return;
            Task t1 = null;
            Task t2 = null;
            if (use1)
            {
                t1 = Task.Run(() =>
                {
                    Cylinder _changeCylinder = MachineResource.Instance.MachineCylinder[$"Arm1变距气缸"];
                    string putPosPrepare = "";
                    string putPos = "";
                    //Arm1精定位上层GRR取料位置
                    if (_isFront)
                    {
                        putPos = upReady ? $"Arm1精定位上层GRR取料位置" : $"Arm1精定位下层GRR取料位置";
                        putPosPrepare = upReady ? "Arm1精定位上层GRR取料位置预备" : "Arm1精定位下层GRR取料位置预备";
                        _changeCylinder = MachineResource.Instance.MachineCylinder[$"Arm1变距气缸"];
                    }
                    else
                    {
                        putPos = upReady ? $"Arm3精定位上层GRR取料位置" : $"Arm3精定位下层GRR取料位置";
                        putPosPrepare = upReady ? "Arm3精定位上层GRR取料位置预备" : "Arm3精定位下层GRR取料位置预备";
                        _changeCylinder = MachineResource.Instance.MachineCylinder[$"Arm3变距气缸"];
                    }
                    SingleAxisMove2Point(_y1, "旋转位");
                    if (!CheckFlowCondition()) return;
                    AxisMoveSimultaneously(new List<Axis>() { _x1, _r1 }, putPosPrepare);
                    if (!CheckFlowCondition()) return;
                    SingleAxisMove2Point(_y1, putPosPrepare);
                    if (!CheckFlowCondition()) return;
                    List<bool> productStatus = new List<bool>();
                    productStatus = feedTray1.Helper.Select(c => c.Status == CellStatus.HasProduct).ToList();
                    //string zPos = "";
                    string precisionName = "";
                    if (_isFront)
                    {
                        //zPos = upReady ? "Arm1精定位上层放料高度" : "Arm1精定位下层放料高度";
                        precisionName = "精定位移载1";
                    }
                    else
                    {
                        //zPos = upReady ? "Arm3精定位上层放料高度" : "Arm3精定位下层放料高度";
                        precisionName = "精定位移载2";
                    }
                    //if (_isFront)
                    //{
                    //    NozzlePutProductExtDoE2(_z1,
                    //                       _feedCylinders1,
                    //                       _feedVacs1,
                    //                       _feedRevVacs1,
                    //                       upReady ? _precisionUpRecycleVacs1 : _precisionDownRecycleVacs1,
                    //                       upReady ? _upPositionCylinder1 : _downPositionCylinder1,
                    //                       checkChangeCylinder: _changeCylinder,
                    //                       _x1,
                    //                       _y1,
                    //                       putPos,
                    //                       putPosPrepare,
                    //                       _z1.MotionPosition[upPos],
                    //                       zPutRelPos: SystemConfig.Instance.TestParam.ArmZHValuePutInPrecision,
                    //                       zPutRelPosSpeed: SystemConfig.Instance.TestParam.ArmZHValueSpeedPutInPrecision,
                    //                       _isFront ? SystemConfig.Instance.ArmPutPrecisionParam[0].NozzleTimeOut : SystemConfig.Instance.ArmPutPrecisionParam[2].NozzleTimeOut,
                    //                       _isFront ? SystemConfig.Instance.ArmPutPrecisionParam[0].DelayBeforeNozzleUp : SystemConfig.Instance.ArmPutPrecisionParam[2].DelayBeforeNozzleUp,
                    //                       productStatus,
                    //                       clampDelayCylinderAfter: upReady ? SystemConfig.Instance.UsingStatus.ClampPrecisionDelayInArmUp : SystemConfig.Instance.UsingStatus.ClampPrecisionDelayInArmDown,
                    //                       clampDelayCylinderBefore: upReady ? SystemConfig.Instance.UsingStatus.ClampPrecisionDelayBeforeInArmUp : SystemConfig.Instance.UsingStatus.ClampPrecisionDelayBeforeInArmDown);

                    //}
                    //else
                    {
                        NozzlePutProductExtDoE2(_z1,
                                              _feedCylinders1,
                                              _feedVacs1,
                                              _feedRevVacs1,
                                              vacOther: null,
                                              upReady ? _upRecyclePositionCylinder[1] : _downRecyclePositionCylinder[1],
                                              checkChangeCylinder: _changeCylinder,
                                              _x1,
                                              _y1,
                                              putPos,
                                              putPosPrepare,
                                              _z1.MotionPosition[upPos],
                                              zPutRelPos: SystemConfig.Instance.TestParam.ArmZHValuePutInPrecision,
                                              zPutRelPosSpeed: SystemConfig.Instance.TestParam.ArmZHValueSpeedPutInPrecision,
                                              _isFront ? SystemConfig.Instance.ArmPutPrecisionParam[0].NozzleTimeOut : SystemConfig.Instance.ArmPutPrecisionParam[2].NozzleTimeOut,
                                              _isFront ? SystemConfig.Instance.ArmPutPrecisionParam[0].DelayBeforeNozzleUp : SystemConfig.Instance.ArmPutPrecisionParam[2].DelayBeforeNozzleUp,
                                              productStatus,
                                              clampDelayCylinderAfter: upReady ? SystemConfig.Instance.UsingStatus.ClampPrecisionDelayInArmUp : SystemConfig.Instance.UsingStatus.ClampPrecisionDelayInArmDown,
                                              clampDelayCylinderBefore: upReady ? SystemConfig.Instance.UsingStatus.ClampPrecisionDelayBeforeInArmUp : SystemConfig.Instance.UsingStatus.ClampPrecisionDelayBeforeInArmDown);


                    }
                    if (!CheckFlowCondition()) return;
                    //交换料状态
                    //productStatus.Reverse();
                    Tray precisionRecycleTray = upReady ? (_flowManager.SelectFlow(precisionName) as PrecisionLogic).GetRecycleTray1Up() : (_flowManager.SelectFlow(precisionName) as PrecisionLogic).GetRecycleTray1Down();
                    for (int i = 0; i < productStatus.Count; i++)
                    {
                        if (productStatus[i])
                        {
                            if (i == 0)
                            {
                                precisionRecycleTray.Helper.SetCellStatus(0, feedTray1.Helper.GetCell(0).Status);
                                precisionRecycleTray.Helper.SetCellBarcode(0, feedTray1.Helper.GetCell(0).SN);
                                precisionRecycleTray.Helper.SetCellResult(0, feedTray1.Helper.GetCell(0).Result);
                                precisionRecycleTray.Helper.SetCellTesters(0, feedTray1.Helper.GetCell(0).TestedTesters);

                                feedTray1.Helper.SetCellStatus(0, CellStatus.NoProduct);
                                feedTray1.Helper.SetCellBarcode(0, string.Empty);
                                feedTray1.Helper.SetCellResult(0, TestResult.NoTest);
                            }
                            else
                            {
                                precisionRecycleTray.Helper.SetCellStatus(1, feedTray1.Helper.GetCell(1).Status);
                                precisionRecycleTray.Helper.SetCellBarcode(1, feedTray1.Helper.GetCell(1).SN);
                                precisionRecycleTray.Helper.SetCellResult(1, feedTray1.Helper.GetCell(1).Result);
                                precisionRecycleTray.Helper.SetCellTesters(1, feedTray1.Helper.GetCell(1).TestedTesters);

                                feedTray1.Helper.SetCellStatus(1, CellStatus.NoProduct);
                                feedTray1.Helper.SetCellBarcode(1, string.Empty);
                                feedTray1.Helper.SetCellResult(1, TestResult.NoTest);
                            }
                        }
                    }
                });
            }
            if (use2)
            {
                t2 = Task.Run(() =>
                {
                    Cylinder _changeCylinder = MachineResource.Instance.MachineCylinder[$"Arm2变距气缸"];
                    string putPosPrepare = "";
                    string putPos = "";
                    if (_isFront)
                    {
                        putPos = upReady ? $"Arm2精定位上层GRR取料位置" : $"Arm2精定位下层GRR取料位置";
                        putPosPrepare = upReady ? $"Arm2精定位上层GRR取料位置预备" : $"Arm2精定位下层GRR取料位置预备";
                        _changeCylinder = MachineResource.Instance.MachineCylinder[$"Arm2变距气缸"];
                    }
                    else
                    {
                        putPos = upReady ? $"Arm4精定位上层GRR取料位置" : $"Arm4精定位下层GRR取料位置";
                        putPosPrepare = upReady ? $"Arm4精定位上层GRR取料位置预备" : $"Arm4精定位下层GRR取料位置预备";
                        _changeCylinder = MachineResource.Instance.MachineCylinder[$"Arm4变距气缸"];
                    }
                    SingleAxisMove2Point(_y2, "旋转位");
                    if (!CheckFlowCondition()) return;
                    AxisMoveSimultaneously(new List<Axis>() { _x2, _r2 }, putPosPrepare);
                    if (!CheckFlowCondition()) return;
                    SingleAxisMove2Point(_y2, putPosPrepare);
                    if (!CheckFlowCondition()) return;

                    List<bool> productStatus = new List<bool>();
                    //if (_isFront)
                    //    productStatus = recycleTray2.Helper.Select(c => c.Status == CellStatus.HasProduct).Reverse().ToList();
                    //else
                    productStatus = feedTray2.Helper.Select(c => c.Status == CellStatus.HasProduct).ToList();
                    //string zPos = "";
                    string precisionName = "";
                    if (_isFront)
                    {
                        //zPos = upReady ? "Arm2精定位上层放料高度" : "Arm2精定位下层放料高度";
                        precisionName = "精定位移载1";
                    }
                    else
                    {
                        //zPos = upReady ? "Arm4精定位上层放料高度" : "Arm4精定位下层放料高度";
                        precisionName = "精定位移载2";
                    }
                    //if (_isFront)
                    //{
                    //    NozzlePutProductExtDoE2(_z2,
                    //                        _feedCylinders2,
                    //                        _feedVacs2,
                    //                        _feedRevVacs2,
                    //                        upReady ? _precisionUpRecycleVacs2 : _precisionDownRecycleVacs2,
                    //                        upReady ? _upPositionCylinder2 : _downPositionCylinder2,
                    //                        checkChangeCylinder: _changeCylinder,
                    //                        _x2,
                    //                        _y2,
                    //                        putPos,
                    //                        putPosPrepare,
                    //                        _z2.MotionPosition[upPos],
                    //                        zPutRelPos: SystemConfig.Instance.TestParam.ArmZHValuePutInPrecision,
                    //                        zPutRelPosSpeed: SystemConfig.Instance.TestParam.ArmZHValueSpeedPutInPrecision,
                    //                        _isFront ? SystemConfig.Instance.ArmPutPrecisionParam[1].NozzleTimeOut : SystemConfig.Instance.ArmPutPrecisionParam[3].NozzleTimeOut,
                    //                        _isFront ? SystemConfig.Instance.ArmPutPrecisionParam[1].DelayBeforeNozzleUp : SystemConfig.Instance.ArmPutPrecisionParam[3].DelayBeforeNozzleUp,
                    //                        productStatus,
                    //                        clampDelayCylinderAfter: upReady ? SystemConfig.Instance.UsingStatus.ClampPrecisionDelayInArmUp : SystemConfig.Instance.UsingStatus.ClampPrecisionDelayInArmDown,
                    //                        clampDelayCylinderBefore: upReady ? SystemConfig.Instance.UsingStatus.ClampPrecisionDelayBeforeInArmUp : SystemConfig.Instance.UsingStatus.ClampPrecisionDelayBeforeInArmDown);
                    //}
                    //else
                    {
                        NozzlePutProductExtDoE2(_z2,
                                            _feedCylinders2,
                                            _feedVacs2,
                                            _feedRevVacs2,
                                            vacOther: null,
                                            upReady ? _upRecyclePositionCylinder[0] : _downRecyclePositionCylinder[0],
                                            checkChangeCylinder: _changeCylinder,
                                            _x2,
                                            _y2,
                                            putPos,
                                            putPosPrepare,
                                            _z2.MotionPosition[upPos],
                                            zPutRelPos: SystemConfig.Instance.TestParam.ArmZHValuePutInPrecision,
                                            zPutRelPosSpeed: SystemConfig.Instance.TestParam.ArmZHValueSpeedPutInPrecision,
                                            _isFront ? SystemConfig.Instance.ArmPutPrecisionParam[1].NozzleTimeOut : SystemConfig.Instance.ArmPutPrecisionParam[3].NozzleTimeOut,
                                            _isFront ? SystemConfig.Instance.ArmPutPrecisionParam[1].DelayBeforeNozzleUp : SystemConfig.Instance.ArmPutPrecisionParam[3].DelayBeforeNozzleUp,
                                            productStatus,
                                            clampDelayCylinderAfter: upReady ? SystemConfig.Instance.UsingStatus.ClampPrecisionDelayInArmUp : SystemConfig.Instance.UsingStatus.ClampPrecisionDelayInArmDown,
                                            clampDelayCylinderBefore: upReady ? SystemConfig.Instance.UsingStatus.ClampPrecisionDelayBeforeInArmUp : SystemConfig.Instance.UsingStatus.ClampPrecisionDelayBeforeInArmDown);

                    }
                    if (!CheckFlowCondition()) return;
                    //string pointName = "";
                    //if (_isFront)
                    //{
                    //    pointName = upReady ? "Arm2精定位上层取料位置" : "Arm2精定位下层取料位置";
                    //}
                    //else
                    //{
                    //    pointName = upReady ? "Arm4精定位上层取料位置" : "Arm4精定位下层取料位置";
                    //}
                    //SingleAxisMove2Point(_x2, pointName);
                    if (!CheckFlowCondition()) return;
                    //交换料状态
                    //if (_isFront)
                    //    productStatus.Reverse();
                    Tray precisionRecycleTray = upReady ? (_flowManager.SelectFlow(precisionName) as PrecisionLogic).GetRecycleTray2Up() : (_flowManager.SelectFlow(precisionName) as PrecisionLogic).GetRecycleTray2Down();
                    for (int i = 0; i < productStatus.Count; i++)
                    {
                        if (_isFront)
                        {
                            if (productStatus[i])
                            {
                                if (i == 0)
                                {
                                    precisionRecycleTray.Helper.SetCellStatus(0, feedTray2.Helper.GetCell(0).Status);
                                    precisionRecycleTray.Helper.SetCellBarcode(0, feedTray2.Helper.GetCell(0).SN);
                                    precisionRecycleTray.Helper.SetCellResult(0, feedTray2.Helper.GetCell(0).Result);
                                    precisionRecycleTray.Helper.SetCellTesters(0, feedTray2.Helper.GetCell(0).TestedTesters);

                                    feedTray2.Helper.SetCellStatus(0, CellStatus.NoProduct);
                                    feedTray2.Helper.SetCellBarcode(0, string.Empty);
                                    feedTray2.Helper.SetCellResult(0, TestResult.NoTest);
                                }
                                else
                                {
                                    precisionRecycleTray.Helper.SetCellStatus(1, feedTray2.Helper.GetCell(1).Status);
                                    precisionRecycleTray.Helper.SetCellBarcode(1, feedTray2.Helper.GetCell(1).SN);
                                    precisionRecycleTray.Helper.SetCellResult(1, feedTray2.Helper.GetCell(1).Result);
                                    precisionRecycleTray.Helper.SetCellTesters(1, feedTray2.Helper.GetCell(1).TestedTesters);

                                    feedTray2.Helper.SetCellStatus(1, CellStatus.NoProduct);
                                    feedTray2.Helper.SetCellBarcode(1, string.Empty);
                                    feedTray2.Helper.SetCellResult(1, TestResult.NoTest);
                                }
                            }
                        }
                        else
                        {
                            if (i == 0)
                            {
                                precisionRecycleTray.Helper.SetCellStatus(1, feedTray2.Helper.GetCell(0).Status);
                                precisionRecycleTray.Helper.SetCellBarcode(1, feedTray2.Helper.GetCell(0).SN);
                                precisionRecycleTray.Helper.SetCellResult(1, feedTray2.Helper.GetCell(0).Result);
                                precisionRecycleTray.Helper.SetCellTesters(1, feedTray2.Helper.GetCell(0).TestedTesters);

                                feedTray2.Helper.SetCellStatus(0, CellStatus.NoProduct);
                                feedTray2.Helper.SetCellBarcode(0, string.Empty);
                                feedTray2.Helper.SetCellResult(0, TestResult.NoTest);
                            }
                            else
                            {
                                precisionRecycleTray.Helper.SetCellStatus(0, feedTray2.Helper.GetCell(1).Status);
                                precisionRecycleTray.Helper.SetCellBarcode(0, feedTray2.Helper.GetCell(1).SN);
                                precisionRecycleTray.Helper.SetCellResult(0, feedTray2.Helper.GetCell(1).Result);
                                precisionRecycleTray.Helper.SetCellTesters(0, feedTray2.Helper.GetCell(1).TestedTesters);

                                feedTray2.Helper.SetCellStatus(1, CellStatus.NoProduct);
                                feedTray2.Helper.SetCellBarcode(1, string.Empty);
                                feedTray2.Helper.SetCellResult(1, TestResult.NoTest);
                            }
                        }
                    }
                });
            }
            if (use1 && use2)
                Task.WaitAll(t1, t2);
            else if (use1)
                Task.WaitAll(t1);
            else if (use2)
                Task.WaitAll(t2);
            if (!CheckFlowCondition()) return;
        }
        public void PutOKLeft(bool upReady, Tray recycleTray1)
        {
            string upPos = upReady ? "放上层OK料后抬升位" : "放下层OK料后抬升位";
            AxisMoveSimultaneously(new List<Axis>() { _z1, _z2 }, "待机位");
            if (!CheckFlowCondition()) return;

            safetyCheck(upReady);
            if (!CheckFlowCondition()) return;
            string putPosPrepare = "";
            string putPos = "";
            if (_isFront)
            {
                putPos = upReady ? $"Arm1精定位上层放料位置" : $"Arm1精定位下层放料位置";
                putPosPrepare = upReady ? "Arm1精定位上层放料位置预备" : "Arm1精定位下层放料位置预备";
            }
            else
            {
                putPos = upReady ? $"Arm3精定位上层放料位置" : $"Arm3精定位下层放料位置";
                putPosPrepare = upReady ? "Arm3精定位上层放料位置预备" : "Arm3精定位下层放料位置预备";
            }
            SingleAxisMove2Point(_y1, "旋转位");
            if (!CheckFlowCondition()) return;
            AxisMoveSimultaneously(new List<Axis>() { _x1, _r1 }, putPosPrepare);
            if (!CheckFlowCondition()) return;
            SingleAxisMove2Point(_y1, putPosPrepare);
            if (!CheckFlowCondition()) return;
            List<bool> productStatus = new List<bool>();
            productStatus = recycleTray1.Helper.Select(c => c.Status == CellStatus.HasProduct).ToList();
            //string zPos = "";
            string precisionName = "";
            if (_isFront)
            {
                //zPos = upReady ? "Arm1精定位上层放料高度" : "Arm1精定位下层放料高度";
                precisionName = "精定位移载1";
            }
            else
            {
                //zPos = upReady ? "Arm3精定位上层放料高度" : "Arm3精定位下层放料高度";
                precisionName = "精定位移载2";
            }
            NozzlePutProductExtDoE(_z1,
                                _recycleCylinders1,
                                _recycleVacs1,
                                _recycleRevVacs1,
                                vacOther: null,
                                _x1,
                                _y1,
                                putPos,
                                putPosPrepare,
                                _z1.MotionPosition[upPos],
                                _isFront ? SystemConfig.Instance.ArmPutPrecisionParam[0].NozzleTimeOut : SystemConfig.Instance.ArmPutPrecisionParam[2].NozzleTimeOut,
                                _isFront ? SystemConfig.Instance.ArmPutPrecisionParam[0].DelayBeforeNozzleUp : SystemConfig.Instance.ArmPutPrecisionParam[2].DelayBeforeNozzleUp,
                                productStatus);
            if (!CheckFlowCondition()) return;
            //交换料状态
            //productStatus.Reverse();
            Tray precisionRecycleTray = upReady ? (_flowManager.SelectFlow(precisionName) as PrecisionLogic).GetRecycleTray1Up() : (_flowManager.SelectFlow(precisionName) as PrecisionLogic).GetRecycleTray1Down();
            for (int i = 0; i < productStatus.Count; i++)
            {
                if (productStatus[i])
                {
                    if (i == 0)
                    {
                        precisionRecycleTray.Helper.SetCellStatus(1, recycleTray1.Helper.GetCell(0).Status);
                        precisionRecycleTray.Helper.SetCellBarcode(1, recycleTray1.Helper.GetCell(0).SN);
                        precisionRecycleTray.Helper.SetCellResult(1, recycleTray1.Helper.GetCell(0).Result);
                        precisionRecycleTray.Helper.SetCellTesters(1, recycleTray1.Helper.GetCell(0).TestedTesters);

                        recycleTray1.Helper.SetCellStatus(0, CellStatus.NoProduct);
                        recycleTray1.Helper.SetCellBarcode(0, string.Empty);
                        recycleTray1.Helper.SetCellResult(0, TestResult.NoTest);
                    }
                    else
                    {
                        precisionRecycleTray.Helper.SetCellStatus(0, recycleTray1.Helper.GetCell(1).Status);
                        precisionRecycleTray.Helper.SetCellBarcode(0, recycleTray1.Helper.GetCell(1).SN);
                        precisionRecycleTray.Helper.SetCellResult(0, recycleTray1.Helper.GetCell(1).Result);
                        precisionRecycleTray.Helper.SetCellTesters(0, recycleTray1.Helper.GetCell(1).TestedTesters);

                        recycleTray1.Helper.SetCellStatus(1, CellStatus.NoProduct);
                        recycleTray1.Helper.SetCellBarcode(1, string.Empty);
                        recycleTray1.Helper.SetCellResult(1, TestResult.NoTest);
                    }
                }
            }
            if (!CheckFlowCondition()) return;
        }
        public void PutOKRight(bool upReady, Tray recycleTray2)
        {
            string upPos = upReady ? "放上层OK料后抬升位" : "放下层OK料后抬升位";
            AxisMoveSimultaneously(new List<Axis>() { _z1, _z2 }, "待机位");
            if (!CheckFlowCondition()) return;

            safetyCheck(upReady);
            if (!CheckFlowCondition()) return;
            string putPosPrepare = "";
            string putPos = "";
            if (_isFront)
            {
                putPos = upReady ? $"Arm2精定位上层放料位置" : $"Arm2精定位下层放料位置";
                putPosPrepare = upReady ? $"Arm2精定位上层放料位置预备" : $"Arm2精定位下层放料位置预备";
            }
            else
            {
                putPos = upReady ? $"Arm4精定位上层放料位置" : $"Arm4精定位下层放料位置";
                putPosPrepare = upReady ? $"Arm4精定位上层放料位置预备" : $"Arm4精定位下层放料位置预备";
            }
            SingleAxisMove2Point(_y2, "旋转位");
            if (!CheckFlowCondition()) return;
            AxisMoveSimultaneously(new List<Axis>() { _x2, _r2 }, putPosPrepare);
            if (!CheckFlowCondition()) return;
            SingleAxisMove2Point(_y2, putPosPrepare);
            if (!CheckFlowCondition()) return;

            List<bool> productStatus = new List<bool>();
            //if (_isFront)
            //    productStatus = recycleTray2.Helper.Select(c => c.Status == CellStatus.HasProduct).Reverse().ToList();
            //else
            productStatus = recycleTray2.Helper.Select(c => c.Status == CellStatus.HasProduct).ToList();
            //string zPos = "";
            string precisionName = "";
            if (_isFront)
            {
                //zPos = upReady ? "Arm2精定位上层放料高度" : "Arm2精定位下层放料高度";
                precisionName = "精定位移载1";
            }
            else
            {
                //zPos = upReady ? "Arm4精定位上层放料高度" : "Arm4精定位下层放料高度";
                precisionName = "精定位移载2";
            }
            NozzlePutProductExtDoE(_z2,
                                _recycleCylinders2,
                                _recycleVacs2,
                                _recycleRevVacs2,
                                vacOther: null,
                                _x2,
                                _y2,
                                putPos,
                                putPosPrepare,
                                _z2.MotionPosition[upPos],
                                _isFront ? SystemConfig.Instance.ArmPutPrecisionParam[1].NozzleTimeOut : SystemConfig.Instance.ArmPutPrecisionParam[3].NozzleTimeOut,
                                _isFront ? SystemConfig.Instance.ArmPutPrecisionParam[1].DelayBeforeNozzleUp : SystemConfig.Instance.ArmPutPrecisionParam[3].DelayBeforeNozzleUp,
                                productStatus);
            if (!CheckFlowCondition()) return;
            string pointName = "";
            if (_isFront)
            {
                pointName = upReady ? "Arm2精定位上层取料位置" : "Arm2精定位下层取料位置";
            }
            else
            {
                pointName = upReady ? "Arm4精定位上层取料位置" : "Arm4精定位下层取料位置";
            }
            SingleAxisMove2Point(_x2, pointName);
            if (!CheckFlowCondition()) return;
            //交换料状态
            //if (_isFront)
            //    productStatus.Reverse();
            Tray precisionRecycleTray = upReady ? (_flowManager.SelectFlow(precisionName) as PrecisionLogic).GetRecycleTray2Up() : (_flowManager.SelectFlow(precisionName) as PrecisionLogic).GetRecycleTray2Down();
            for (int i = 0; i < productStatus.Count; i++)
            {
                if (_isFront)
                {
                    if (productStatus[i])
                    {
                        if (i == 0)
                        {
                            precisionRecycleTray.Helper.SetCellStatus(1, recycleTray2.Helper.GetCell(0).Status);
                            precisionRecycleTray.Helper.SetCellBarcode(1, recycleTray2.Helper.GetCell(0).SN);
                            precisionRecycleTray.Helper.SetCellResult(1, recycleTray2.Helper.GetCell(0).Result);
                            precisionRecycleTray.Helper.SetCellTesters(1, recycleTray2.Helper.GetCell(0).TestedTesters);

                            recycleTray2.Helper.SetCellStatus(0, CellStatus.NoProduct);
                            recycleTray2.Helper.SetCellBarcode(0, string.Empty);
                            recycleTray2.Helper.SetCellResult(0, TestResult.NoTest);
                        }
                        else
                        {
                            precisionRecycleTray.Helper.SetCellStatus(0, recycleTray2.Helper.GetCell(1).Status);
                            precisionRecycleTray.Helper.SetCellBarcode(0, recycleTray2.Helper.GetCell(1).SN);
                            precisionRecycleTray.Helper.SetCellResult(0, recycleTray2.Helper.GetCell(1).Result);
                            precisionRecycleTray.Helper.SetCellTesters(0, recycleTray2.Helper.GetCell(1).TestedTesters);

                            recycleTray2.Helper.SetCellStatus(1, CellStatus.NoProduct);
                            recycleTray2.Helper.SetCellBarcode(1, string.Empty);
                            recycleTray2.Helper.SetCellResult(1, TestResult.NoTest);
                        }
                    }
                }
                else
                {
                    if (productStatus[i])
                    {
                        precisionRecycleTray.Helper.SetCellStatus(i, recycleTray2.Helper.GetCell(i).Status);
                        precisionRecycleTray.Helper.SetCellBarcode(i, recycleTray2.Helper.GetCell(i).SN);
                        precisionRecycleTray.Helper.SetCellResult(i, recycleTray2.Helper.GetCell(i).Result);
                        precisionRecycleTray.Helper.SetCellTesters(i, recycleTray2.Helper.GetCell(i).TestedTesters);

                        recycleTray2.Helper.SetCellStatus(i, CellStatus.NoProduct);
                        recycleTray2.Helper.SetCellBarcode(i, string.Empty);
                        recycleTray2.Helper.SetCellResult(i, TestResult.NoTest);
                    }
                }
            }
            if (!CheckFlowCondition()) return;
        }
        public void GetOK(bool upReady, Tray feedTray1, Tray feedTray2, bool use1 = true, bool use2 = true)
        {
            string upPos = "待机位";
            AxisMoveSimultaneously(new List<Axis>() { _z1, _z2 }, "待机位");
            if (!CheckFlowCondition()) return;

            safetyCheck(upReady);
            if (!CheckFlowCondition()) return;
            Task t1 = null;
            Task t2 = null;
            if (use1)
            {
                t1 = Task.Run(() =>
                {
                    string getPos = "";
                    if (_isFront)
                        getPos = upReady ? $"Arm1精定位上层GRR取料位置" : $"Arm1精定位下层GRR取料位置";
                    else
                        getPos = upReady ? $"Arm3精定位上层GRR取料位置" : $"Arm3精定位下层GRR取料位置";
                    SingleAxisMove2Point(_y1, "旋转位");
                    if (!CheckFlowCondition()) return;
                    AxisMoveSimultaneously(new List<Axis>() { _x1, _r1 }, getPos);
                    if (!CheckFlowCondition()) return;
                    SingleAxisMove2Point(_y1, getPos);
                    if (!CheckFlowCondition()) return;
                    string zPos = "";
                    string precisionName = "";
                    string localName = "";
                    if (_isFront)
                    {
                        zPos = upReady ? "Arm1精定位上层GRR取料位置" : "Arm1精定位下层GRR取料位置";
                        precisionName = "精定位移载1";
                        localName = upReady ? "Arm1精定位上层" : "Arm1精定位下层"; 
                    }
                    else
                    {
                        zPos = upReady ? "Arm3精定位上层GRR取料位置" : "Arm3精定位下层GRR取料位置";
                        precisionName = "精定位移载2";
                        localName = upReady ? "Arm3精定位上层" : "Arm3精定位下层";
                    }
                    Tray precisionRecycleTray = upReady ? (_flowManager.SelectFlow(precisionName) as PrecisionLogic).GetRecycleTray1Up() : (_flowManager.SelectFlow(precisionName) as PrecisionLogic).GetRecycleTray1Down();
                    List<bool> productStatus = precisionRecycleTray.Helper.Select(c => c.Status == CellStatus.HasProduct).ToList();
                    NozzleGetProductExt(_z1,
                                        _feedCylinders1,
                                        _feedVacs1,
                                        _feedVacSenses1,
                                        vacOther: null,
                                        null,
                                        zPos,
                                        upPos,
                                        localName:$"{localName}:",
                                        5000,
                                        500,
                                        500,
                                        GlobalVariable.IsDryRun,
                                        productStatus);
                    if (!CheckFlowCondition()) return;
                    //交换料状态
                    for (int i = 0; i < productStatus.Count; i++)
                    {
                        if (productStatus[i])
                        {
                            feedTray1.Helper.SetCellStatus(i, precisionRecycleTray.Helper.GetCell(i).Status);
                            feedTray1.Helper.SetCellBarcode(i, precisionRecycleTray.Helper.GetCell(i).SN);
                            feedTray1.Helper.SetCellResult(i, precisionRecycleTray.Helper.GetCell(i).Result);
                            feedTray1.Helper.SetCellTesters(i, precisionRecycleTray.Helper.GetCell(i).TestedTesters);
                            feedTray1.Helper.GetCell(i).IsUp = true;

                            precisionRecycleTray.Helper.SetCellStatus(i, CellStatus.NoProduct);
                            precisionRecycleTray.Helper.SetCellBarcode(i, string.Empty);
                            precisionRecycleTray.Helper.SetCellResult(i, TestResult.NoTest);
                        }
                    }
                });
            }
            if (use2)
            {
                t2 = Task.Run(() =>
                {
                    string putPos = "";
                    if (_isFront)
                        putPos = upReady ? $"Arm2精定位上层GRR取料位置" : $"Arm2精定位下层GRR取料位置";
                    else
                        putPos = upReady ? $"Arm4精定位上层GRR取料位置" : $"Arm4精定位下层GRR取料位置";
                    SingleAxisMove2Point(_y2, "旋转位");
                    if (!CheckFlowCondition()) return;
                    AxisMoveSimultaneously(new List<Axis>() { _x2, _r2 }, putPos);
                    if (!CheckFlowCondition()) return;
                    SingleAxisMove2Point(_y2, putPos);
                    if (!CheckFlowCondition()) return;
                    string zPos = "";
                    string precisionName = "";
                    string localName = "";
                    if (_isFront)
                    {
                        zPos = upReady ? "Arm2精定位上层GRR取料位置" : "Arm2精定位下层GRR取料位置";
                        precisionName = "精定位移载1";
                        localName = upReady ? "Arm2精定位上层" : "Arm2精定位下层";
                    }
                    else
                    {
                        zPos = upReady ? "Arm4精定位上层GRR取料位置" : "Arm4精定位下层GRR取料位置";
                        precisionName = "精定位移载2";
                        localName = upReady ? "Arm4精定位上层" : "Arm4精定位下层";
                    }
                    Tray precisionRecycleTray = upReady ? (_flowManager.SelectFlow(precisionName) as PrecisionLogic).GetRecycleTray2Up() : (_flowManager.SelectFlow(precisionName) as PrecisionLogic).GetRecycleTray2Down();
                    List<bool> productStatus = precisionRecycleTray.Helper.Select(c => c.Status == CellStatus.HasProduct).ToList();
                    NozzleGetProductExt(_z2,
                                        _feedCylinders2,
                                        _feedVacs2,
                                        _feedVacSenses2,
                                        vacOther: null,
                                        null,
                                        zPos,
                                        upPos,
                                        localName: $"{localName}:",
                                        5000,
                                        500,
                                        500,
                                        GlobalVariable.IsDryRun,
                                        productStatus);
                    if (!CheckFlowCondition()) return;
                    //交换料状态
                    for (int i = 0; i < productStatus.Count; i++)
                    {
                        if (productStatus[i])
                        {
                            feedTray2.Helper.SetCellStatus(i, precisionRecycleTray.Helper.GetCell(i).Status);
                            feedTray2.Helper.SetCellBarcode(i, precisionRecycleTray.Helper.GetCell(i).SN);
                            feedTray2.Helper.SetCellResult(i, precisionRecycleTray.Helper.GetCell(i).Result);
                            feedTray2.Helper.SetCellTesters(i, precisionRecycleTray.Helper.GetCell(i).TestedTesters);
                            feedTray2.Helper.GetCell(i).IsUp = true;

                            precisionRecycleTray.Helper.SetCellStatus(i, CellStatus.NoProduct);
                            precisionRecycleTray.Helper.SetCellBarcode(i, string.Empty);
                            precisionRecycleTray.Helper.SetCellResult(i, TestResult.NoTest);
                        }
                    }
                });
            }

            if (use1 && use2)
                Task.WaitAll(t1, t2);
            else if (use1)
                Task.WaitAll(t1);
            else if (use2)
                Task.WaitAll(t2);
            if (!CheckFlowCondition()) return;
        }
        public void GetOKLeft(bool upReady, Tray feedTray1)
        {
            string upPos = "待机位";
            AxisMoveSimultaneously(new List<Axis>() { _z1, _z2 }, "待机位");
            if (!CheckFlowCondition()) return;

            safetyCheck(upReady);
            if (!CheckFlowCondition()) return;
            string getPos = "";
            if (_isFront)
                getPos = upReady ? $"Arm1精定位上层GRR取料位置" : $"Arm1精定位下层GRR取料位置";
            else
                getPos = upReady ? $"Arm3精定位上层GRR取料位置" : $"Arm3精定位下层GRR取料位置";
            SingleAxisMove2Point(_y1, "旋转位");
            if (!CheckFlowCondition()) return;
            AxisMoveSimultaneously(new List<Axis>() { _x1, _r1 }, getPos);
            if (!CheckFlowCondition()) return;
            SingleAxisMove2Point(_y1, getPos);
            if (!CheckFlowCondition()) return;
            string zPos = "";
            string precisionName = "";
            string localName = "";
            if (_isFront)
            {
                zPos = upReady ? "Arm1精定位上层GRR取料位置" : "Arm1精定位下层GRR取料位置";
                precisionName = "精定位移载1";
                localName = upReady ? "Arm1精定位上层" : "Arm1精定位下层";
            }
            else
            {
                zPos = upReady ? "Arm3精定位上层GRR取料位置" : "Arm3精定位下层GRR取料位置";
                precisionName = "精定位移载2";
                localName = upReady ? "Arm3精定位上层" : "Arm3精定位下层";
            }
            Tray precisionRecycleTray = upReady ? (_flowManager.SelectFlow(precisionName) as PrecisionLogic).GetRecycleTray1Up() : (_flowManager.SelectFlow(precisionName) as PrecisionLogic).GetRecycleTray1Down();
            List<bool> productStatus = precisionRecycleTray.Helper.Select(c => c.Status == CellStatus.HasProduct).ToList();
            NozzleGetProductExt(_z1,
                                _feedCylinders1,
                                _feedVacs1,
                                _feedVacSenses1,
                                vacOther: null,
                                null,
                                zPos,
                                upPos,
                                localName: $"{localName}:",
                                5000,
                                500,
                                500,
                                GlobalVariable.IsDryRun,
                                productStatus);
            if (!CheckFlowCondition()) return;
            //交换料状态
            for (int i = 0; i < productStatus.Count; i++)
            {
                if (productStatus[i])
                {
                    feedTray1.Helper.SetCellStatus(i, precisionRecycleTray.Helper.GetCell(i).Status);
                    feedTray1.Helper.SetCellBarcode(i, precisionRecycleTray.Helper.GetCell(i).SN);
                    feedTray1.Helper.SetCellResult(i, precisionRecycleTray.Helper.GetCell(i).Result);
                    feedTray1.Helper.SetCellTesters(i, precisionRecycleTray.Helper.GetCell(i).TestedTesters);
                    feedTray1.Helper.GetCell(i).IsUp = true;

                    precisionRecycleTray.Helper.SetCellStatus(i, CellStatus.NoProduct);
                    precisionRecycleTray.Helper.SetCellBarcode(i, string.Empty);
                    precisionRecycleTray.Helper.SetCellResult(i, TestResult.NoTest);
                }
            }
            if (!CheckFlowCondition()) return;
        }
        public void GetOKRight(bool upReady, Tray feedTray2)
        {
            string upPos = "待机位";
            AxisMoveSimultaneously(new List<Axis>() { _z1, _z2 }, "待机位");
            if (!CheckFlowCondition()) return;

            safetyCheck(upReady);
            if (!CheckFlowCondition()) return;
            string putPos = "";
            if (_isFront)
                putPos = upReady ? $"Arm2精定位上层GRR取料位置" : $"Arm2精定位下层GRR取料位置";
            else
                putPos = upReady ? $"Arm4精定位上层GRR取料位置" : $"Arm4精定位下层GRR取料位置";
            SingleAxisMove2Point(_y2, "旋转位");
            if (!CheckFlowCondition()) return;
            AxisMoveSimultaneously(new List<Axis>() { _x2, _r2 }, putPos);
            if (!CheckFlowCondition()) return;
            SingleAxisMove2Point(_y2, putPos);
            if (!CheckFlowCondition()) return;
            string zPos = "";
            string precisionName = "";
            string localName = "";
            if (_isFront)
            {
                zPos = upReady ? "Arm2精定位上层GRR取料位置" : "Arm2精定位下层GRR取料位置";
                precisionName = "精定位移载1";
                localName = upReady ? "Arm2精定位上层" : "Arm2精定位下层";
            }
            else
            {
                zPos = upReady ? "Arm4精定位上层GRR取料位置" : "Arm4精定位下层GRR取料位置";
                precisionName = "精定位移载2";
                localName = upReady ? "Arm4精定位上层" : "Arm4精定位下层";
            }
            Tray precisionRecycleTray = upReady ? (_flowManager.SelectFlow(precisionName) as PrecisionLogic).GetRecycleTray2Up() : (_flowManager.SelectFlow(precisionName) as PrecisionLogic).GetRecycleTray2Down();
            List<bool> productStatus = precisionRecycleTray.Helper.Select(c => c.Status == CellStatus.HasProduct).ToList();
            NozzleGetProductExt(_z2,
                                _feedCylinders2,
                                _feedVacs2,
                                _feedVacSenses2,
                                vacOther: null,
                                null,
                                zPos,
                                upPos,
                                localName: $"{localName}:",
                                5000,
                                500,
                                500,
                                GlobalVariable.IsDryRun,
                                productStatus);
            if (!CheckFlowCondition()) return;
            //交换料状态
            for (int i = 0; i < productStatus.Count; i++)
            {
                if (productStatus[i])
                {
                    feedTray2.Helper.SetCellStatus(i, precisionRecycleTray.Helper.GetCell(i).Status);
                    feedTray2.Helper.SetCellBarcode(i, precisionRecycleTray.Helper.GetCell(i).SN);
                    feedTray2.Helper.SetCellResult(i, precisionRecycleTray.Helper.GetCell(i).Result);
                    feedTray2.Helper.SetCellTesters(i, precisionRecycleTray.Helper.GetCell(i).TestedTesters);
                    feedTray2.Helper.GetCell(i).IsUp = true;

                    precisionRecycleTray.Helper.SetCellStatus(i, CellStatus.NoProduct);
                    precisionRecycleTray.Helper.SetCellBarcode(i, string.Empty);
                    precisionRecycleTray.Helper.SetCellResult(i, TestResult.NoTest);
                }
            }
            if (!CheckFlowCondition()) return;
        }
        public void useOK2Position(bool upReady, int headerIndex)
        {
            safetyCheck(upReady);
            if (!CheckFlowCondition()) return;
            string putPos = "";
            string getPos = "";
            string zPos = "";
            string localName = "";
            if (_isFront)
            {
                putPos = upReady ? $"Arm{headerIndex + 1}精定位上层放复测料位置" : $"Arm{headerIndex + 1}精定位下层放复测料位置";
                getPos = upReady ? $"Arm{headerIndex + 1}精定位上层取复测料位置" : $"Arm{headerIndex + 1}精定位下层取复测料位置";
                zPos = upReady ? $"Arm{headerIndex + 1}精定位上层放料高度" : $"Arm{headerIndex + 1}精定位下层放料高度";
                localName = upReady ? $"Arm{headerIndex + 1}精定位上层" : $"Arm{headerIndex + 1}精定位下层";
            }
            else
            {
                putPos = upReady ? $"Arm{headerIndex + 3}精定位上层放复测料位置" : $"Arm{headerIndex + 3}精定位下层放复测料位置";
                getPos = upReady ? $"Arm{headerIndex + 3}精定位上层取复测料位置" : $"Arm{headerIndex + 3}精定位下层取复测料位置";
                zPos = upReady ? $"Arm{headerIndex + 3}精定位上层放料高度" : $"Arm{headerIndex + 3}精定位下层放料高度";
                localName = upReady ? $"Arm{headerIndex + 3}精定位上层" : $"Arm{headerIndex + 3}精定位下层";
            }
            if (headerIndex == 0)
            {
                AxisMoveSimultaneously(new List<Axis>() { _x1, _y1, _r1 }, putPos);
                if (!CheckFlowCondition()) return;
                NozzlePutProductExt(_z1,
                                    _feedCylinders1,
                                    _feedVacs1,
                                    _feedRevVacs1,
                                    vacOther: null,
                                    zPos,
                                    _z1.MotionPosition[zPos] - 20,
                                    5000,
                                    500,
                                    new List<bool>() { true, true });
                if (!CheckFlowCondition()) return;
                //进行精定位动作
                //if (_isFront)
                //{
                //    if (upReady)
                //    {
                //        MultiCylinderOperate(new List<Cylinder>() { _upPositionCylinder1, _upPositionCylinder2 }, 5000, new List<bool>() { true, true });
                //        if (!CheckFlowCondition()) return;
                //        Thread.Sleep(200);
                //        MultiCylinderOperate(new List<Cylinder>() { _upPositionCylinder1, _upPositionCylinder2 }, 5000, new List<bool>() { false, false });
                //        if (!CheckFlowCondition()) return;
                //    }
                //    else
                //    {
                //        MultiCylinderOperate(new List<Cylinder>() { _downPositionCylinder1, _downPositionCylinder2 }, 5000, new List<bool>() { true, true });
                //        if (!CheckFlowCondition()) return;
                //        Thread.Sleep(200);
                //        MultiCylinderOperate(new List<Cylinder>() { _downPositionCylinder1, _downPositionCylinder2 }, 5000, new List<bool>() { false, false });
                //        if (!CheckFlowCondition()) return;
                //    }
                //}
                //else
                {
                    //进行精定位动作
                    if (upReady)
                    {
                        MultiCylinderOperate(_upRecyclePositionCylinder, 5000, new List<bool>() { true, true });
                        if (!CheckFlowCondition()) return;
                        Thread.Sleep(200);
                        MultiCylinderOperate(_upRecyclePositionCylinder, 5000, new List<bool>() { false, false });
                        if (!CheckFlowCondition()) return;
                    }
                    else
                    {
                        MultiCylinderOperate(_downRecyclePositionCylinder, 5000, new List<bool>() { true, true });
                        if (!CheckFlowCondition()) return;
                        Thread.Sleep(200);
                        MultiCylinderOperate(_downRecyclePositionCylinder, 5000, new List<bool>() { false, false });
                        if (!CheckFlowCondition()) return;
                    }
                }
                AxisMoveSimultaneously(new List<Axis>() { _x1, _y1, _r1 }, getPos);
                if (!CheckFlowCondition()) return;
                //取料
                NozzleGetProductExt(_z1,
                                    _feedCylinders1,
                                    _feedVacs1,
                                    _feedVacSenses1,
                                    vacOther: null,
                                    null,
                                    zPos,
                                    "待机位",
                                    localName: $"{localName}:",
                                    5000,
                                    500,
                                    500,
                                    GlobalVariable.IsDryRun);
                if (!CheckFlowCondition()) return;
            }
            else
            {
                AxisMoveSimultaneously(new List<Axis>() { _x2, _y2, _r2 }, putPos);
                if (!CheckFlowCondition()) return;
                NozzlePutProductExt(_z2,
                                    _feedCylinders2,
                                    _feedVacs2,
                                    _feedRevVacs2,
                                    vacOther: null,
                                    zPos,
                                    _z2.MotionPosition[zPos] - 20,
                                    5000,
                                    500,
                                    new List<bool>() { true, true });
                if (!CheckFlowCondition()) return;
                //进行精定位动作
                //if (_isFront)
                //{
                //    if (upReady)
                //    {
                //        MultiCylinderOperate(new List<Cylinder>() { _upPositionCylinder1, _upPositionCylinder2 }, 5000, new List<bool>() { true, true });
                //        if (!CheckFlowCondition()) return;
                //        Thread.Sleep(200);
                //        MultiCylinderOperate(new List<Cylinder>() { _upPositionCylinder1, _upPositionCylinder2 }, 5000, new List<bool>() { false, false });
                //        if (!CheckFlowCondition()) return;
                //    }
                //    else
                //    {
                //        MultiCylinderOperate(new List<Cylinder>() { _downPositionCylinder1, _downPositionCylinder2 }, 5000, new List<bool>() { true, true });
                //        if (!CheckFlowCondition()) return;
                //        Thread.Sleep(200);
                //        MultiCylinderOperate(new List<Cylinder>() { _downPositionCylinder1, _downPositionCylinder2 }, 5000, new List<bool>() { false, false });
                //        if (!CheckFlowCondition()) return;
                //    }
                //}
                //else
                {
                    //进行精定位动作
                    if (upReady)
                    {
                        MultiCylinderOperate(_upRecyclePositionCylinder, 5000, new List<bool>() { true, true });
                        if (!CheckFlowCondition()) return;
                        Thread.Sleep(200);
                        MultiCylinderOperate(_upRecyclePositionCylinder, 5000, new List<bool>() { false, false });
                        if (!CheckFlowCondition()) return;
                    }
                    else
                    {
                        MultiCylinderOperate(_downRecyclePositionCylinder, 5000, new List<bool>() { true, true });
                        if (!CheckFlowCondition()) return;
                        Thread.Sleep(200);
                        MultiCylinderOperate(_downRecyclePositionCylinder, 5000, new List<bool>() { false, false });
                        if (!CheckFlowCondition()) return;
                    }
                }
                AxisMoveSimultaneously(new List<Axis>() { _x2, _y2, _r2 }, getPos);
                if (!CheckFlowCondition()) return;
                //取料
                NozzleGetProductExt(_z2,
                                    _feedCylinders2,
                                    _feedVacs2,
                                    _feedVacSenses2,
                                    vacOther: null,
                                    null,
                                    zPos,
                                    "待机位",
                                    localName: $"{localName}:",
                                    5000,
                                    500,
                                    500,
                                    GlobalVariable.IsDryRun);
                if (!CheckFlowCondition()) return;
            }
        }
        public void useWait2Position(bool upReady, int headerIndex)
        {
            safetyCheck(upReady);
            if (!CheckFlowCondition()) return;
            string putPosDownPre = "";
            string localName = "";
            if (_isFront)
            {
                putPosDownPre = upReady ? $"Arm{headerIndex + 1}点检定位位置上层待测预备" : $"Arm{headerIndex + 1}点检定位位置下层待测预备";
            }
            else
            {
                putPosDownPre = upReady ? $"Arm{headerIndex + 3}点检定位位置上层待测预备" : $"Arm{headerIndex + 3}点检定位位置下层待测预备";
            }
            string putPosDown = "";
            if (_isFront)
            {
                putPosDown = upReady ? $"Arm{headerIndex + 1}点检定位位置上层待测" : $"Arm{headerIndex + 1}点检定位位置下层待测";
            }
            else
            {
                putPosDown = upReady ? $"Arm{headerIndex + 3}点检定位位置上层待测" : $"Arm{headerIndex + 3}点检定位位置下层待测";
            }
            string putPos = "";
            if (_isFront)
            {
                putPos = upReady ? $"Arm{headerIndex + 1}精定位上层取料位置" : $"Arm{headerIndex + 1}精定位下层取料位置";
                localName = upReady ? $"Arm{headerIndex + 1}精定位上层" : $"Arm{headerIndex + 1}精定位下层";
            }
            else
            {
                putPos = upReady ? $"Arm{headerIndex + 3}精定位上层取料位置" : $"Arm{headerIndex + 3}精定位下层取料位置";
                localName = upReady ? $"Arm{headerIndex + 3}精定位上层" : $"Arm{headerIndex + 3}精定位下层";
            }
            if (headerIndex == 0)
            {
                AxisMoveSimultaneously(new List<Axis>() { _x1, _y1, _r1 }, putPosDownPre);
                if (!CheckFlowCondition()) return;
                NozzlePutProductExtDoE(_z1,
                                    _feedCylinders1,
                                    _feedVacs1,
                                    _feedRevVacs1,
                                    vacOther: null,
                                    _x1,
                                    _y1,
                                    putPosDown,
                                    putPosDownPre,
                                    _z1.MotionPosition[putPosDownPre] - 20,
                                    5000,
                                    500,
                                    new List<bool>() { true, true });
                if (!CheckFlowCondition()) return;
                //进行精定位动作
                //if (_isFront)
                //{
                //    if (upReady)
                //    {
                //        MultiCylinderOperate(_precisionUpFeedVacs1, 5000, new List<bool>() { false, false });
                //        if (!CheckFlowCondition()) return;
                //        Thread.Sleep(200);
                //        MultiCylinderOperate(new List<Cylinder>() { _upPositionCylinder1, _upPositionCylinder2 }, 5000, new List<bool>() { true, true });
                //        if (!CheckFlowCondition()) return;
                //        Thread.Sleep(500);
                //        MultiCylinderOperate(_precisionUpFeedVacs1, 5000, new List<bool>() { true, true });
                //        if (!CheckFlowCondition()) return;
                //        Thread.Sleep(200);
                //        MultiCylinderOperate(new List<Cylinder>() { _upPositionCylinder1, _upPositionCylinder2 }, 5000, new List<bool>() { false, false });
                //        if (!CheckFlowCondition()) return;
                //    }
                //    else
                //    {
                //        MultiCylinderOperate(_precisionDownFeedVacs1, 5000, new List<bool>() { false, false });
                //        if (!CheckFlowCondition()) return;
                //        Thread.Sleep(200);
                //        MultiCylinderOperate(new List<Cylinder>() { _downPositionCylinder1, _downPositionCylinder2 }, 5000, new List<bool>() { true, true });
                //        if (!CheckFlowCondition()) return;
                //        Thread.Sleep(500);
                //        MultiCylinderOperate(_precisionDownFeedVacs1, 5000, new List<bool>() { true, true });
                //        if (!CheckFlowCondition()) return;
                //        Thread.Sleep(200);
                //        MultiCylinderOperate(new List<Cylinder>() { _downPositionCylinder1, _downPositionCylinder2 }, 5000, new List<bool>() { false, false });
                //        if (!CheckFlowCondition()) return;
                //    }
                //}
                //else
                {
                    if (upReady)
                    {
                        //MultiCylinderOperate(_precisionUpFeedVacs1, 5000, new List<bool>() { false, false });
                        //if (!CheckFlowCondition()) return;
                        Thread.Sleep(200);
                        MultiCylinderOperate(_upFeedPositionCylinder, 5000, new List<bool>() { true, true });
                        if (!CheckFlowCondition()) return;
                        //Thread.Sleep(500);
                        //MultiCylinderOperate(_precisionUpFeedVacs1, 5000, new List<bool>() { true, true });
                        //if (!CheckFlowCondition()) return;
                        Thread.Sleep(200);
                        MultiCylinderOperate(_upFeedPositionCylinder, 5000, new List<bool>() { false, false });
                        if (!CheckFlowCondition()) return;
                    }
                    else
                    {
                        //MultiCylinderOperate(_precisionDownFeedVacs1, 5000, new List<bool>() { false, false });
                        //if (!CheckFlowCondition()) return;
                        Thread.Sleep(200);
                        MultiCylinderOperate(_downFeedPositionCylinder, 5000, new List<bool>() { true, true });
                        if (!CheckFlowCondition()) return;
                        //Thread.Sleep(500);
                        //MultiCylinderOperate(_precisionDownFeedVacs1, 5000, new List<bool>() { true, true });
                        //if (!CheckFlowCondition()) return;
                        Thread.Sleep(200);
                        MultiCylinderOperate(_downFeedPositionCylinder, 5000, new List<bool>() { false, false });
                        if (!CheckFlowCondition()) return;
                    }
                }
                AxisMoveSimultaneously(new List<Axis>() { _x1, _y1, _r1 }, putPos);
                if (!CheckFlowCondition()) return;
                //取料
                NozzleGetProductExt(_z1,
                                    _feedCylinders1,
                                    _feedVacs1,
                                    _feedVacSenses1,
                                    vacOther: null,
                                    null,
                                    putPos,
                                    "待机位",
                                    localName:$"{localName}:",
                                    5000,
                                    500,
                                    500,
                                    GlobalVariable.IsDryRun);
                if (!CheckFlowCondition()) return;
            }
            else
            {
                AxisMoveSimultaneously(new List<Axis>() { _x2, _y2, _r2 }, putPosDownPre);
                if (!CheckFlowCondition()) return;
                NozzlePutProductExtDoE(_z2,
                                    _feedCylinders2,
                                    _feedVacs2,
                                    _feedRevVacs2,
                                    vacOther: null,
                                    _x2,
                                    _y2,
                                    putPosDown,
                                    putPosDownPre,
                                    _z2.MotionPosition[putPosDownPre] - 20,
                                    5000,
                                    500,
                                    new List<bool>() { true, true });
                if (!CheckFlowCondition()) return;
                //进行精定位动作
                //if (_isFront)
                //{
                //    if (upReady)
                //    {
                //        MultiCylinderOperate(_precisionUpFeedVacs2, 5000, new List<bool>() { false, false });
                //        if (!CheckFlowCondition()) return;
                //        Thread.Sleep(200);
                //        MultiCylinderOperate(new List<Cylinder>() { _upPositionCylinder1, _upPositionCylinder2 }, 5000, new List<bool>() { true, true });
                //        if (!CheckFlowCondition()) return;
                //        Thread.Sleep(500);
                //        MultiCylinderOperate(_precisionUpFeedVacs2, 5000, new List<bool>() { true, true });
                //        if (!CheckFlowCondition()) return;
                //        Thread.Sleep(200);
                //        MultiCylinderOperate(new List<Cylinder>() { _upPositionCylinder1, _upPositionCylinder2 }, 5000, new List<bool>() { false, false });
                //        if (!CheckFlowCondition()) return;
                //    }
                //    else
                //    {
                //        MultiCylinderOperate(_precisionDownFeedVacs2, 5000, new List<bool>() { false, false });
                //        if (!CheckFlowCondition()) return;
                //        Thread.Sleep(200);
                //        MultiCylinderOperate(new List<Cylinder>() { _downPositionCylinder1, _downPositionCylinder2 }, 5000, new List<bool>() { true, true });
                //        if (!CheckFlowCondition()) return;
                //        Thread.Sleep(500);
                //        MultiCylinderOperate(_precisionDownFeedVacs2, 5000, new List<bool>() { true, true });
                //        if (!CheckFlowCondition()) return;
                //        Thread.Sleep(200);
                //        MultiCylinderOperate(new List<Cylinder>() { _downPositionCylinder1, _downPositionCylinder2 }, 5000, new List<bool>() { false, false });
                //        if (!CheckFlowCondition()) return;
                //    }
                //}
                //else
                {
                    if (upReady)
                    {
                        //MultiCylinderOperate(_precisionUpFeedVacs2, 5000, new List<bool>() { false, false });
                        //if (!CheckFlowCondition()) return;
                        Thread.Sleep(200);
                        MultiCylinderOperate(_upFeedPositionCylinder, 5000, new List<bool>() { true, true });
                        if (!CheckFlowCondition()) return;
                        //Thread.Sleep(500);
                        //MultiCylinderOperate(_precisionUpFeedVacs2, 5000, new List<bool>() { true, true });
                        //if (!CheckFlowCondition()) return;
                        Thread.Sleep(200);
                        MultiCylinderOperate(_upFeedPositionCylinder, 5000, new List<bool>() { false, false });
                        if (!CheckFlowCondition()) return;
                    }
                    else
                    {
                        //MultiCylinderOperate(_precisionDownFeedVacs2, 5000, new List<bool>() { false, false });
                        //if (!CheckFlowCondition()) return;
                        Thread.Sleep(200);
                        MultiCylinderOperate(_downFeedPositionCylinder, 5000, new List<bool>() { true, true });
                        if (!CheckFlowCondition()) return;
                        //Thread.Sleep(500);
                        //MultiCylinderOperate(_precisionDownFeedVacs2, 5000, new List<bool>() { true, true });
                        //if (!CheckFlowCondition()) return;
                        Thread.Sleep(200);
                        MultiCylinderOperate(_downFeedPositionCylinder, 5000, new List<bool>() { false, false });
                        if (!CheckFlowCondition()) return;
                    }
                }
                AxisMoveSimultaneously(new List<Axis>() { _x2, _y2, _r2 }, putPos);
                if (!CheckFlowCondition()) return;
                //取料
                NozzleGetProductExt(_z2,
                                    _feedCylinders2,
                                    _feedVacs2,
                                    _feedVacSenses2,
                                    vacOther: null,
                                    null,
                                    putPos,
                                    "待机位",
                                    localName: $"{localName}:",
                                    5000,
                                    500,
                                    500,
                                    GlobalVariable.IsDryRun);
                if (!CheckFlowCondition()) return;
            }
        }
        public void useWait2PositionRecycle(bool upReady, int headerIndex)
        {
            Tray recycleTray1 = null;
            Tray recycleTray2 = null;
            Tray feedTray1 = null;
            Tray feedTray2 = null;

            if (_isFront)
            {
                recycleTray1 = (_flowManager.SelectFlow("Arm1模组") as TransferLogic).GetRecycleTray();
                recycleTray2 = (_flowManager.SelectFlow("Arm2模组") as TransferLogic).GetRecycleTray();
                feedTray1 = (_flowManager.SelectFlow("Arm1模组") as TransferLogic).GetFeedTray();
                feedTray2 = (_flowManager.SelectFlow("Arm2模组") as TransferLogic).GetFeedTray();
            }
            else
            {
                recycleTray1 = (_flowManager.SelectFlow("Arm3模组") as TransferLogic).GetRecycleTray();
                recycleTray2 = (_flowManager.SelectFlow("Arm4模组") as TransferLogic).GetRecycleTray();
                feedTray1 = (_flowManager.SelectFlow("Arm3模组") as TransferLogic).GetFeedTray();
                feedTray2 = (_flowManager.SelectFlow("Arm4模组") as TransferLogic).GetFeedTray();
            }

            safetyCheck(upReady);
            if (!CheckFlowCondition()) return;
            string putPosPre = "";
         
            if (_isFront)
            {
                putPosPre = upReady ? $"Arm{headerIndex + 1}点检定位位置上层已测预备" : $"Arm{headerIndex + 1}点检定位位置下层已测预备";
            }
            else
            {
                putPosPre = upReady ? $"Arm{headerIndex + 3}点检定位位置上层已测预备" : $"Arm{headerIndex + 3}点检定位位置下层已测预备";
            }
            string putPos = "";
            if (_isFront)
            {
                putPos = upReady ? $"Arm{headerIndex + 1}点检定位位置上层已测" : $"Arm{headerIndex + 1}点检定位位置下层已测";
            }
            else
            {
                putPos = upReady ? $"Arm{headerIndex + 3}点检定位位置上层已测" : $"Arm{headerIndex + 3}点检定位位置下层已测";
            }
            if (headerIndex == 0)
            {
                SingleAxisMove2Point(_y1, "旋转位");
                if (!CheckFlowCondition()) return;
                AxisMoveSimultaneously(new List<Axis>() { _x1, _r1 }, putPosPre);
                if (!CheckFlowCondition()) return;
                SingleAxisMove2Point(_y1, putPosPre);
                if (!CheckFlowCondition()) return;
                NozzlePutProductExtDoE(_z1,
                                    _recycleCylinders1,
                                    _recycleVacs1,
                                    _recycleRevVacs1,
                                    vacOther: null,
                                    _x1,
                                    _y1,
                                    putPos,
                                    putPosPre,
                                    _z1.MotionPosition["待机位"],
                                    5000,
                                    500,
                                    new List<bool>() { true, true });
                if (!CheckFlowCondition()) return;
                //进行精定位动作
                //if (_isFront)
                //{
                //    if (upReady)
                //    {
                //        MultiCylinderOperate(_precisionUpFeedVacs1, 5000, new List<bool>() { false, false });
                //        Thread.Sleep(200);
                //        if (!CheckFlowCondition()) return;
                //        MultiCylinderOperate(new List<Cylinder>() { _upPositionCylinder1, _upPositionCylinder2 }, 5000, new List<bool>() { true, true });
                //        if (!CheckFlowCondition()) return;
                //        Thread.Sleep(500);
                //        MultiCylinderOperate(_precisionUpFeedVacs1, 5000, new List<bool>() { true, true });
                //        Thread.Sleep(200);
                //        MultiCylinderOperate(new List<Cylinder>() { _upPositionCylinder1, _upPositionCylinder2 }, 5000, new List<bool>() { false, false });
                //        if (!CheckFlowCondition()) return;
                //    }
                //    else
                //    {
                //        MultiCylinderOperate(_precisionDownFeedVacs1, 5000, new List<bool>() { false, false });
                //        Thread.Sleep(200);
                //        MultiCylinderOperate(new List<Cylinder>() { _downPositionCylinder1, _downPositionCylinder2 }, 5000, new List<bool>() { true, true });
                //        if (!CheckFlowCondition()) return;
                //        Thread.Sleep(500);
                //        MultiCylinderOperate(_precisionDownFeedVacs1, 5000, new List<bool>() { true, true });
                //        Thread.Sleep(200);
                //        MultiCylinderOperate(new List<Cylinder>() { _downPositionCylinder1, _downPositionCylinder2 }, 5000, new List<bool>() { false, false });
                //        if (!CheckFlowCondition()) return;
                //    }
                //}
                //else
                {
                    if (upReady)
                    {
                        //MultiCylinderOperate(_precisionUpFeedVacs1, 5000, new List<bool>() { false, false });
                        Thread.Sleep(200);
                        if (!CheckFlowCondition()) return;
                        MultiCylinderOperate(_upFeedPositionCylinder, 5000, new List<bool>() { true, true });
                        if (!CheckFlowCondition()) return;
                        Thread.Sleep(500);
                        //MultiCylinderOperate(_precisionUpFeedVacs1, 5000, new List<bool>() { true, true });
                        //Thread.Sleep(200);
                        MultiCylinderOperate(_upFeedPositionCylinder, 5000, new List<bool>() { false, false });
                        if (!CheckFlowCondition()) return;
                    }
                    else
                    {
                        //MultiCylinderOperate(_precisionDownFeedVacs1, 5000, new List<bool>() { false, false });
                        Thread.Sleep(200);
                        MultiCylinderOperate(_downFeedPositionCylinder, 5000, new List<bool>() { true, true });
                        if (!CheckFlowCondition()) return;
                        Thread.Sleep(500);
                        //MultiCylinderOperate(_precisionDownFeedVacs1, 5000, new List<bool>() { true, true });
                        //Thread.Sleep(200);
                        MultiCylinderOperate(_downFeedPositionCylinder, 5000, new List<bool>() { false, false });
                        if (!CheckFlowCondition()) return;
                    }
                }
                SingleAxisMove2Point(_y1, "旋转位");
                if (!CheckFlowCondition()) return;
                string getPos = "";
                string localName = "";
                if (_isFront)
                {
                    getPos = upReady ? $"Arm{headerIndex + 1}精定位上层取料位置" : $"Arm{headerIndex + 1}精定位下层取料位置";
                    localName = upReady ? $"Arm{headerIndex + 1}精定位上层" : $"Arm{headerIndex + 1}精定位下层";
                }
                else
                {
                    getPos = upReady ? $"Arm{headerIndex + 3}精定位上层取料位置" : $"Arm{headerIndex + 3}精定位下层取料位置";
                    localName = upReady ? $"Arm{headerIndex + 3}精定位上层" : $"Arm{headerIndex + 3}精定位下层";
                }
                AxisMoveSimultaneously(new List<Axis>() { _x1, _r1 }, getPos);
                if (!CheckFlowCondition()) return;
                SingleAxisMove2Point(_y1, getPos);
                if (!CheckFlowCondition()) return;
                //取料
                NozzleGetProductExt(_z1,
                                    _feedCylinders1,
                                    _feedVacs1,
                                    _feedVacSenses1,
                                    vacOther: null,
                                    null,
                                    getPos,
                                    "待机位",
                                    localName:$"{localName}:",
                                    5000,
                                    500,
                                    500,
                                    GlobalVariable.IsDryRun);
                if (!CheckFlowCondition()) return;

                for (int i = 0; i < 2; i++)
                {
                    if (i == 0)
                    {
                        feedTray1.Helper.SetCellStatus(1, recycleTray1.Helper.GetCell(0).Status);
                        feedTray1.Helper.SetCellBarcode(1, recycleTray1.Helper.GetCell(0).SN);
                        feedTray1.Helper.SetCellResult(1, recycleTray1.Helper.GetCell(0).Result);
                        feedTray1.Helper.SetCellTesters(1, recycleTray1.Helper.GetCell(0).TestedTesters);

                        recycleTray1.Helper.SetCellStatus(0, CellStatus.NoProduct);
                        recycleTray1.Helper.SetCellBarcode(0, string.Empty);
                        recycleTray1.Helper.SetCellResult(0, TestResult.NoTest);
                    }
                    else
                    {
                        feedTray1.Helper.SetCellStatus(0, recycleTray1.Helper.GetCell(1).Status);
                        feedTray1.Helper.SetCellBarcode(0, recycleTray1.Helper.GetCell(1).SN);
                        feedTray1.Helper.SetCellResult(0, recycleTray1.Helper.GetCell(1).Result);
                        feedTray1.Helper.SetCellTesters(0, recycleTray1.Helper.GetCell(1).TestedTesters);

                        recycleTray1.Helper.SetCellStatus(1, CellStatus.NoProduct);
                        recycleTray1.Helper.SetCellBarcode(1, string.Empty);
                        recycleTray1.Helper.SetCellResult(1, TestResult.NoTest);
                    }
                }
            }
            else
            {
                SingleAxisMove2Point(_y2, "旋转位");
                if (!CheckFlowCondition()) return;
                AxisMoveSimultaneously(new List<Axis>() { _x2, _r2 }, putPosPre);
                if (!CheckFlowCondition()) return;
                SingleAxisMove2Point(_y2, putPosPre);
                if (!CheckFlowCondition()) return;
                NozzlePutProductExtDoE(_z2,
                                    _recycleCylinders2,
                                    _recycleVacs2,
                                    _recycleRevVacs2,
                                    vacOther: null,
                                    _x2,
                                    _y2,
                                    putPos,
                                    putPosPre,
                                    _z2.MotionPosition["待机位"],
                                    5000,
                                    500,
                                    new List<bool>() { true, true });
                if (!CheckFlowCondition()) return;
                //进行精定位动作
                //if (_isFront)
                //{
                //    if (upReady)
                //    {
                //        MultiCylinderOperate(_precisionUpFeedVacs2, 5000, new List<bool>() { false, false });
                //        Thread.Sleep(200);
                //        MultiCylinderOperate(new List<Cylinder>() { _upPositionCylinder1, _upPositionCylinder2 }, 5000, new List<bool>() { true, true });
                //        if (!CheckFlowCondition()) return;
                //        Thread.Sleep(500);
                //        MultiCylinderOperate(_precisionUpFeedVacs2, 5000, new List<bool>() { true, true });
                //        Thread.Sleep(200);
                //        MultiCylinderOperate(new List<Cylinder>() { _upPositionCylinder1, _upPositionCylinder2 }, 5000, new List<bool>() { false, false });
                //        if (!CheckFlowCondition()) return;
                //    }
                //    else
                //    {
                //        MultiCylinderOperate(_precisionDownFeedVacs2, 5000, new List<bool>() { false, false });
                //        Thread.Sleep(200);
                //        MultiCylinderOperate(new List<Cylinder>() { _downPositionCylinder1, _downPositionCylinder2 }, 5000, new List<bool>() { true, true });
                //        if (!CheckFlowCondition()) return;
                //        Thread.Sleep(500);
                //        MultiCylinderOperate(_precisionDownFeedVacs2, 5000, new List<bool>() { true, true });
                //        Thread.Sleep(200);
                //        MultiCylinderOperate(new List<Cylinder>() { _downPositionCylinder1, _downPositionCylinder2 }, 5000, new List<bool>() { false, false });
                //        if (!CheckFlowCondition()) return;
                //    }
                //}
                //else
                {
                    if (upReady)
                    {
                        //MultiCylinderOperate(_precisionUpFeedVacs2, 5000, new List<bool>() { false, false });
                        Thread.Sleep(200);
                        MultiCylinderOperate(_upFeedPositionCylinder, 5000, new List<bool>() { true, true });
                        if (!CheckFlowCondition()) return;
                        Thread.Sleep(500);
                        //MultiCylinderOperate(_precisionUpFeedVacs2, 5000, new List<bool>() { true, true });
                        //Thread.Sleep(200);
                        MultiCylinderOperate(_upFeedPositionCylinder, 5000, new List<bool>() { false, false });
                        if (!CheckFlowCondition()) return;
                    }
                    else
                    {
                        //MultiCylinderOperate(_precisionDownFeedVacs2, 5000, new List<bool>() { false, false });
                        Thread.Sleep(200);
                        MultiCylinderOperate(_downFeedPositionCylinder, 5000, new List<bool>() { true, true });
                        if (!CheckFlowCondition()) return;
                        Thread.Sleep(500);
                        //MultiCylinderOperate(_precisionDownFeedVacs2, 5000, new List<bool>() { true, true });
                        //Thread.Sleep(200);
                        MultiCylinderOperate(_downFeedPositionCylinder, 5000, new List<bool>() { false, false });
                        if (!CheckFlowCondition()) return;
                    }
                }
                SingleAxisMove2Point(_y2, "旋转位");
                if (!CheckFlowCondition()) return;
                string getPos = "";
                string localName = "";
                if (_isFront)
                {
                    getPos = upReady ? $"Arm{headerIndex + 1}精定位上层取料位置" : $"Arm{headerIndex + 1}精定位下层取料位置";
                    localName = upReady ? $"Arm{headerIndex + 1}精定位上层" : $"Arm{headerIndex + 1}精定位下层";
                }
                else
                {
                    getPos = upReady ? $"Arm{headerIndex + 3}精定位上层取料位置" : $"Arm{headerIndex + 3}精定位下层取料位置";
                    localName = upReady ? $"Arm{headerIndex + 3}精定位上层" : $"Arm{headerIndex + 3}精定位下层";
                }
                AxisMoveSimultaneously(new List<Axis>() { _x2, _r2 }, getPos);
                if (!CheckFlowCondition()) return;
                SingleAxisMove2Point(_y2, getPos);
                if (!CheckFlowCondition()) return;
                //取料
                NozzleGetProductExt(_z2,
                                    _feedCylinders2,
                                    _feedVacs2,
                                    _feedVacSenses2,
                                    vacOther: null,
                                    null,
                                    getPos,
                                    "待机位",
                                    localName: $"{localName}:",
                                    5000,
                                    500,
                                    500,
                                    GlobalVariable.IsDryRun);
                if (!CheckFlowCondition()) return;

                for (int i = 0; i < 2; i++)
                {
                    if (i == 0)
                    {
                        feedTray2.Helper.SetCellStatus(1, recycleTray2.Helper.GetCell(0).Status);
                        feedTray2.Helper.SetCellBarcode(1, recycleTray2.Helper.GetCell(0).SN);
                        feedTray2.Helper.SetCellResult(1, recycleTray2.Helper.GetCell(0).Result);
                        feedTray2.Helper.SetCellTesters(1, recycleTray2.Helper.GetCell(0).TestedTesters);

                        recycleTray2.Helper.SetCellStatus(0, CellStatus.NoProduct);
                        recycleTray2.Helper.SetCellBarcode(0, string.Empty);
                        recycleTray2.Helper.SetCellResult(0, TestResult.NoTest);
                    }
                    else
                    {
                        feedTray2.Helper.SetCellStatus(0, recycleTray2.Helper.GetCell(1).Status);
                        feedTray2.Helper.SetCellBarcode(0, recycleTray2.Helper.GetCell(1).SN);
                        feedTray2.Helper.SetCellResult(0, recycleTray2.Helper.GetCell(1).Result);
                        feedTray2.Helper.SetCellTesters(0, recycleTray2.Helper.GetCell(1).TestedTesters);

                        recycleTray2.Helper.SetCellStatus(1, CellStatus.NoProduct);
                        recycleTray2.Helper.SetCellBarcode(1, string.Empty);
                        recycleTray2.Helper.SetCellResult(1, TestResult.NoTest);
                    }
                }
            }
        }
        public void putNG(Tray ngTray, string trayName, string avoidPosName, int headerIndex, string nozzleName, int nozzleIndex, Tray recycleTray)
        {
            AxisMoveSimultaneously(new List<Axis>() { _z1, _z2 }, "待机位");
            if (!CheckFlowCondition()) return;
            if (headerIndex == 0)
            {
                int putIndex = ngTray.Helper.GetFirstIndex(CellStatus.NoProduct);
                List<double> pos = new List<double>();
                pos.Add(_x1.MotionPosition[$"{trayName}{nozzleName}-{putIndex}-{0}"]);
                pos.Add(_x2.MotionPosition[avoidPosName]);
                pos.Add(_r1.MotionPosition[$"{trayName}{nozzleName}-{putIndex}-{0}"]);
                pos.Add(_ngAxis.MotionPosition[$"{trayName}{nozzleName}"]);
                SingleAxisMove2Point(_y1, "旋转位");
                if (!CheckFlowCondition()) return;
                AxisMoveSimultaneously(new List<Axis>() { _x1, _x2, _r1, _ngAxis }, pos);
                if (!CheckFlowCondition()) return;
                SingleAxisMove2Point(_y1, $"{trayName}{nozzleName}-{putIndex}-{0}");
                if (!CheckFlowCondition()) return;
                NozzlePutProductExt(_z1,
                                    new List<Cylinder>() { _recycleCylinders1[nozzleIndex] },
                                    new List<Cylinder>() { _recycleVacs1[nozzleIndex] },
                                    new List<Cylinder>() { _recycleRevVacs1[nozzleIndex] },
                                    null,
                                    $"{trayName}{nozzleName}-{putIndex}-{nozzleIndex}",
                                    "待机位",
                                    zRelPos: SystemConfig.Instance.TestParam.ArmZHValuePutInNG,
                                    zRelSpeed: SystemConfig.Instance.TestParam.ArmZHValueSpeedPutInNG,
                                    5000,
                                    100);
                if (!CheckFlowCondition()) return;
                //交换料状态
                ngTray.Helper.SetCellStatus(putIndex, CellStatus.HasProduct);
                ngTray.Helper.SetCellBarcode(putIndex, recycleTray.Helper.GetCell(nozzleIndex).SN);
                ngTray.Helper.SetCellResult(putIndex, recycleTray.Helper.GetCell(nozzleIndex).Result);
                recycleTray.Helper.SetCellStatus(nozzleIndex, CellStatus.NoProduct);
                recycleTray.Helper.SetCellBarcode(nozzleIndex, string.Empty);
                recycleTray.Helper.SetCellResult(nozzleIndex, TestResult.NoTest);
            }
            else if (headerIndex == 1)
            {
                int putIndex = ngTray.Helper.GetFirstIndex(CellStatus.NoProduct);
                List<double> pos = new List<double>();
                pos.Add(_x2.MotionPosition[$"{trayName}{nozzleName}-{putIndex}-{0}"]);
                pos.Add(_x1.MotionPosition[avoidPosName]);
                pos.Add(_y2.MotionPosition[$"{trayName}{nozzleName}-{putIndex}-{0}"]);
                pos.Add(_r2.MotionPosition[$"{trayName}{nozzleName}-{putIndex}-{0}"]);
                AxisMoveSimultaneously(new List<Axis>() { _x2, _x1, _y2, _r2 }, pos);
                if (!CheckFlowCondition()) return;
                NozzlePutProductExt(_z2,
                                    new List<Cylinder>() { _recycleCylinders2[nozzleIndex] },
                                    new List<Cylinder>() { _recycleVacs2[nozzleIndex] },
                                    new List<Cylinder>() { _recycleRevVacs2[nozzleIndex] },
                                    null,
                                    $"{trayName}{nozzleName}-{putIndex}-{nozzleIndex}",
                                    "待机位",
                                    zRelPos: SystemConfig.Instance.TestParam.ArmZHValuePutInNG,
                                    zRelSpeed: SystemConfig.Instance.TestParam.ArmZHValueSpeedPutInNG,
                                    5000,
                                    100);
                if (!CheckFlowCondition()) return;
                //交换料状态
                ngTray.Helper.SetCellStatus(putIndex, CellStatus.HasProduct);
                ngTray.Helper.SetCellBarcode(putIndex, recycleTray.Helper.GetCell(nozzleIndex).SN);
                ngTray.Helper.SetCellResult(putIndex, recycleTray.Helper.GetCell(nozzleIndex).Result);
                recycleTray.Helper.SetCellStatus(nozzleIndex, CellStatus.NoProduct);
                recycleTray.Helper.SetCellBarcode(nozzleIndex, string.Empty);
                recycleTray.Helper.SetCellResult(nozzleIndex, TestResult.NoTest);
            }
        }
        public void putABBNG(Tray ngTray, int headerIndex, string nozzleName, int nozzleIndex, Tray recycleTray, int fixedIndex = -1)
        {
            AxisMoveSimultaneously(new List<Axis>() { _z1, _z2 }, "待机位");
            if (!CheckFlowCondition()) return;
            if (headerIndex == 0)
            {
                int putIndex = ngTray.Helper.GetFirstIndex(CellStatus.NoProduct);
                if (fixedIndex != -1)
                    putIndex = fixedIndex;
                List<double> pos = new List<double>();
                pos.Add(_x1.MotionPosition[$"ABBNG矩阵Arm左{nozzleName}-{putIndex}-{0}"]);
                pos.Add(_x2.MotionPosition["Arm右避让位"]);
                pos.Add(_r1.MotionPosition[$"ABBNG矩阵Arm左{nozzleName}-{putIndex}-{0}"]);
                pos.Add(_ngAxis.MotionPosition[$"{nozzleName}ABB左"]);
                SingleAxisMove2Point(_y1, "旋转位");
                if (!CheckFlowCondition()) return;
                AxisMoveSimultaneously(new List<Axis>() { _x1, _x2, _r1, _ngAxis }, pos);
                if (!CheckFlowCondition()) return;
                SingleAxisMove2Point(_y1, $"ABBNG矩阵Arm左{nozzleName}-{putIndex}-{0}");
                if (!CheckFlowCondition()) return;
                NozzlePutProductExt(_z1,
                                    new List<Cylinder>() { _recycleCylinders1[nozzleIndex] },
                                    new List<Cylinder>() { _recycleVacs1[nozzleIndex] },
                                    new List<Cylinder>() { _recycleRevVacs1[nozzleIndex] },
                                    null,
                                    $"ABBNG矩阵Arm左{nozzleName}-{putIndex}-{0}",
                                    "待机位",
                                    zRelPos: SystemConfig.Instance.TestParam.ArmZHValuePutInNG,
                                    zRelSpeed: SystemConfig.Instance.TestParam.ArmZHValueSpeedPutInNG,
                                    5000,
                                    800);
                if (!CheckFlowCondition()) return;
                //交换料状态
                ngTray.Helper.SetCellStatus(putIndex, CellStatus.HasProduct);
                ngTray.Helper.SetCellBarcode(putIndex, recycleTray.Helper.GetCell(nozzleIndex).SN);
                ngTray.Helper.SetCellResult(putIndex, recycleTray.Helper.GetCell(nozzleIndex).Result);
                ngTray.Helper.SetCellTesters(putIndex, recycleTray.Helper.GetCell(nozzleIndex).TestedTesters);

                recycleTray.Helper.SetCellStatus(nozzleIndex, CellStatus.NoProduct);
                recycleTray.Helper.SetCellBarcode(nozzleIndex, string.Empty);
                recycleTray.Helper.SetCellResult(nozzleIndex, TestResult.NoTest);
            }
            else if (headerIndex == 1)
            {
                int putIndex = ngTray.Helper.GetFirstIndex(CellStatus.NoProduct);
                if (fixedIndex != -1)
                    putIndex = fixedIndex;
                List<double> pos = new List<double>();
                pos.Add(_x2.MotionPosition[$"ABBNG矩阵Arm右{nozzleName}-{putIndex}-{0}"]);
                pos.Add(_x1.MotionPosition["Arm左避让位"]);
                pos.Add(_r2.MotionPosition[$"ABBNG矩阵Arm右{nozzleName}-{putIndex}-{0}"]);
                pos.Add(_ngAxis.MotionPosition[$"{nozzleName}ABB右"]);
                //pos.Add(0);
                SingleAxisMove2Point(_y2, "旋转位");
                if (!CheckFlowCondition()) return;
                AxisMoveSimultaneously(new List<Axis>() { _x2, _x1, _r2, _ngAxis }, pos);
                if (!CheckFlowCondition()) return;
                SingleAxisMove2Point(_y2, $"ABBNG矩阵Arm右{nozzleName}-{putIndex}-{0}");
                if (!CheckFlowCondition()) return;
                NozzlePutProductExt(_z2,
                                    new List<Cylinder>() { _recycleCylinders2[nozzleIndex] },
                                    new List<Cylinder>() { _recycleVacs2[nozzleIndex] },
                                    new List<Cylinder>() { _recycleRevVacs2[nozzleIndex] },
                                    null,
                                    $"ABBNG矩阵Arm右{nozzleName}-{putIndex}-{0}",
                                    "待机位",
                                    zRelPos: SystemConfig.Instance.TestParam.ArmZHValuePutInNG,
                                    zRelSpeed: SystemConfig.Instance.TestParam.ArmZHValueSpeedPutInNG,
                                    5000,
                                    800);
                if (!CheckFlowCondition()) return;
                //交换料状态
                ngTray.Helper.SetCellStatus(putIndex, CellStatus.HasProduct);
                ngTray.Helper.SetCellBarcode(putIndex, recycleTray.Helper.GetCell(nozzleIndex).SN);
                ngTray.Helper.SetCellResult(putIndex, recycleTray.Helper.GetCell(nozzleIndex).Result);
                ngTray.Helper.SetCellTesters(putIndex, recycleTray.Helper.GetCell(nozzleIndex).TestedTesters);

                recycleTray.Helper.SetCellStatus(nozzleIndex, CellStatus.NoProduct);
                recycleTray.Helper.SetCellBarcode(nozzleIndex, string.Empty);
                recycleTray.Helper.SetCellResult(nozzleIndex, TestResult.NoTest);
            }
            lock (GlobalVariable.FrontBackOutputDataLock)
            {
                GlobalVariable.CurrentMachineData.TotalOutputCount += 1;
            }
            lock (GlobalVariable.TesterNGDataLock)
            {
                GlobalVariable.CurrentMachineData.TotalNGCount += 1;
            }
            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Count, GlobalVariable.CurrentMachineData.TotalNGCount.ToString(), this.Description, 0, "NG"));
            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Count, GlobalVariable.CurrentMachineData.TotalOutputCount.ToString(), this.Description, 0, "Output"));
        }
        public void getABBNG(Tray ngTray, int headerIndex, string nozzleName, int nozzleIndex, Tray recycleTray, int fixedIndex = -1)
        {
            AxisMoveSimultaneously(new List<Axis>() { _z1, _z2 }, "待机位");
            if (!CheckFlowCondition()) return;
            if (headerIndex == 0)
            {
                int putIndex = ngTray.Helper.GetFirstIndex(CellStatus.HasProduct);
                if (fixedIndex != -1)
                    putIndex = fixedIndex;
                List<double> pos = new List<double>();
                pos.Add(_x1.MotionPosition[$"ABBNG矩阵Arm左{nozzleName}-{putIndex}-{0}"]);
                pos.Add(_x2.MotionPosition["Arm右避让位"]);
                pos.Add(_r1.MotionPosition[$"ABBNG矩阵Arm左{nozzleName}-{putIndex}-{0}"]);
                pos.Add(_ngAxis.MotionPosition[$"{nozzleName}ABB左"]);
                SingleAxisMove2Point(_y1, "旋转位");
                if (!CheckFlowCondition()) return;
                AxisMoveSimultaneously(new List<Axis>() { _x1, _x2, _r1, _ngAxis }, pos);
                if (!CheckFlowCondition()) return;
                SingleAxisMove2Point(_y1, $"ABBNG矩阵Arm左{nozzleName}-{putIndex}-{0}");
                if (!CheckFlowCondition()) return;
                string localName = "前线ABBNG区";
                NozzleGetProductExt(_z1,
                                    new List<Cylinder>() { _recycleCylinders1[nozzleIndex] },
                                    new List<Cylinder>() { _recycleVacs1[nozzleIndex] },
                                    new List<Sensor>() { _recycleVacSenses1[nozzleIndex] },
                                    null,
                                    null,
                                    $"ABBNG矩阵Arm左{nozzleName}-{putIndex}-{0}",
                                    "待机位",
                                    localName: $"{localName}:",
                                    5000,
                                    500,
                                    500,
                                    GlobalVariable.IsDryRun);
                if (!CheckFlowCondition()) return;
                //交换料状态
                recycleTray.Helper.SetCellStatus(nozzleIndex, CellStatus.HasProduct);
                recycleTray.Helper.SetCellBarcode(nozzleIndex, ngTray.Helper.GetCell(putIndex).SN);
                recycleTray.Helper.SetCellResult(nozzleIndex, ngTray.Helper.GetCell(putIndex).Result);
                recycleTray.Helper.SetCellTesters(nozzleIndex, ngTray.Helper.GetCell(putIndex).TestedTesters);

                ngTray.Helper.SetCellStatus(putIndex, CellStatus.NoProduct);
                ngTray.Helper.SetCellBarcode(putIndex, string.Empty);
                ngTray.Helper.SetCellResult(putIndex, TestResult.NoTest);
            }
            else if (headerIndex == 1)
            {
                int putIndex = ngTray.Helper.GetFirstIndex(CellStatus.HasProduct);
                if (fixedIndex != -1)
                    putIndex = fixedIndex;
                List<double> pos = new List<double>();
                pos.Add(_x2.MotionPosition[$"ABBNG矩阵Arm右{nozzleName}-{putIndex}-{0}"]);
                pos.Add(_x1.MotionPosition["Arm左避让位"]);
                pos.Add(_r2.MotionPosition[$"ABBNG矩阵Arm右{nozzleName}-{putIndex}-{0}"]);
                pos.Add(_ngAxis.MotionPosition[$"{nozzleName}ABB右"]);
                SingleAxisMove2Point(_y2, "旋转位");
                if (!CheckFlowCondition()) return;
                AxisMoveSimultaneously(new List<Axis>() { _x2, _x1, _r2, _ngAxis }, pos);
                if (!CheckFlowCondition()) return;
                SingleAxisMove2Point(_y2, $"ABBNG矩阵Arm右{nozzleName}-{putIndex}-{0}");
                if (!CheckFlowCondition()) return;
                string localName = "后线ABBNG区";
                NozzleGetProductExt(_z2,
                                    new List<Cylinder>() { _recycleCylinders2[nozzleIndex] },
                                    new List<Cylinder>() { _recycleVacs2[nozzleIndex] },
                                    new List<Sensor>() { _recycleVacSenses2[nozzleIndex] },
                                    null,
                                    null,
                                    $"ABBNG矩阵Arm右{nozzleName}-{putIndex}-{0}",
                                    "待机位",
                                    localName: $"{localName}:",
                                    5000,
                                    500,
                                    500,
                                    GlobalVariable.IsDryRun);
                if (!CheckFlowCondition()) return;
                //交换料状态
                recycleTray.Helper.SetCellStatus(nozzleIndex, CellStatus.HasProduct);
                recycleTray.Helper.SetCellBarcode(nozzleIndex, ngTray.Helper.GetCell(putIndex).SN);
                recycleTray.Helper.SetCellResult(nozzleIndex, ngTray.Helper.GetCell(putIndex).Result);
                recycleTray.Helper.SetCellTesters(nozzleIndex, ngTray.Helper.GetCell(putIndex).TestedTesters);

                ngTray.Helper.SetCellStatus(putIndex, CellStatus.NoProduct);
                ngTray.Helper.SetCellBarcode(putIndex, string.Empty);
                ngTray.Helper.SetCellResult(putIndex, TestResult.NoTest);
            }
        }
        public void GetSpotCheck(Tray spotTray, int headerIndex, int spotTrayIndex, string nozzleName, int nozzleIndex, Tray feedTray)
        {
            AxisMoveSimultaneously(new List<Axis>() { _z1, _z2 }, "待机位");
            if (!CheckFlowCondition()) return;
            if (headerIndex == 0)
            {
                List<double> pos = new List<double>();
                pos.Add(_x1.MotionPosition[$"点检矩阵Arm左{nozzleName}-{spotTrayIndex}-{0}"]);
                pos.Add(_x2.MotionPosition["Arm右避让位"]);
                pos.Add(_r1.MotionPosition[$"点检矩阵Arm左{nozzleName}-{spotTrayIndex}-{0}"]);
                pos.Add(_ngAxis.MotionPosition[$"点检矩阵Arm左{nozzleName}"]);
                SingleAxisMove2Point(_y1, "旋转位");
                if (!CheckFlowCondition()) return;
                AxisMoveSimultaneously(new List<Axis>() { _x1, _x2, _r1, _ngAxis }, pos);
                if (!CheckFlowCondition()) return;
                SingleAxisMove2Point(_y1, $"点检矩阵Arm左{nozzleName}-{spotTrayIndex}-{0}");
                if (!CheckFlowCondition()) return;
                string localName = "前线点检区";
                NozzleGetProductExt(_z1,
                                    new List<Cylinder>() { _feedCylinders1[nozzleIndex] },
                                    new List<Cylinder>() { _feedVacs1[nozzleIndex] },
                                    new List<Sensor>() { _feedVacSenses1[nozzleIndex] },
                                    null,
                                    null,
                                    $"点检矩阵Arm左{nozzleName}-{spotTrayIndex}-{0}",
                                    "待机位",
                                    localName: $"{localName}:",
                                    5000,
                                    500,
                                    500,
                                    GlobalVariable.IsDryRun);
                if (!CheckFlowCondition()) return;
                //交换料状态
                feedTray.Helper.SetCellStatus(nozzleIndex, CellStatus.HasProduct);
                feedTray.Helper.SetCellBarcode(nozzleIndex, spotTray.Helper.GetCell(spotTrayIndex).SN);
                feedTray.Helper.SetCellResult(nozzleIndex, spotTray.Helper.GetCell(spotTrayIndex).Result);
                feedTray.Helper.SetCellTesters(nozzleIndex, spotTray.Helper.GetCell(spotTrayIndex).TestedTesters);

                spotTray.Helper.SetCellStatus(spotTrayIndex, CellStatus.NoProduct);
                spotTray.Helper.SetCellBarcode(spotTrayIndex, string.Empty);
                spotTray.Helper.SetCellResult(spotTrayIndex, TestResult.NoTest);
            }
            else if (headerIndex == 1)
            {
                List<double> pos = new List<double>();
                pos.Add(_x2.MotionPosition[$"点检矩阵Arm右{nozzleName}-{spotTrayIndex}-{0}"]);
                pos.Add(_x1.MotionPosition["Arm左避让位"]);
                pos.Add(_r2.MotionPosition[$"点检矩阵Arm右{nozzleName}-{spotTrayIndex}-{0}"]);
                pos.Add(_ngAxis.MotionPosition[$"点检矩阵Arm右{nozzleName}"]);
                SingleAxisMove2Point(_y2, "旋转位");
                if (!CheckFlowCondition()) return;
                AxisMoveSimultaneously(new List<Axis>() { _x2, _x1, _r2, _ngAxis }, pos);
                if (!CheckFlowCondition()) return;
                SingleAxisMove2Point(_y2, $"点检矩阵Arm右{nozzleName}-{spotTrayIndex}-{0}");
                if (!CheckFlowCondition()) return;
                string localName = "后线点检区";
                NozzleGetProductExt(_z2,
                                    new List<Cylinder>() { _feedCylinders2[nozzleIndex] },
                                    new List<Cylinder>() { _feedVacs2[nozzleIndex] },
                                    new List<Sensor>() { _feedVacSenses2[nozzleIndex] },
                                    null,
                                    null,
                                    $"点检矩阵Arm右{nozzleName}-{spotTrayIndex}-{0}",
                                    "待机位",
                                    localName: $"{localName}:",
                                    5000,
                                    500,
                                    500,
                                    GlobalVariable.IsDryRun);
                if (!CheckFlowCondition()) return;
                //交换料状态
                feedTray.Helper.SetCellStatus(nozzleIndex, CellStatus.HasProduct);
                feedTray.Helper.SetCellBarcode(nozzleIndex, spotTray.Helper.GetCell(spotTrayIndex).SN);
                feedTray.Helper.SetCellResult(nozzleIndex, spotTray.Helper.GetCell(spotTrayIndex).Result);
                feedTray.Helper.SetCellTesters(nozzleIndex, spotTray.Helper.GetCell(spotTrayIndex).TestedTesters);

                spotTray.Helper.SetCellStatus(spotTrayIndex, CellStatus.NoProduct);
                spotTray.Helper.SetCellBarcode(spotTrayIndex, string.Empty);
                spotTray.Helper.SetCellResult(spotTrayIndex, TestResult.NoTest);
            }
        }
        public void PutSpotCheck(Tray spotTray, int headerIndex, int spotTrayIndex, string nozzleName, int nozzleIndex, Tray feedTray)
        {
            AxisMoveSimultaneously(new List<Axis>() { _z1, _z2 }, "待机位");
            if (!CheckFlowCondition()) return;
            if (headerIndex == 0)
            {
                SingleAxisMove2Point(_y1, "旋转位");
                if (!CheckFlowCondition()) return;
                List<double> pos = new List<double>();
                pos.Add(_x1.MotionPosition[$"点检矩阵Arm左{nozzleName}-{spotTrayIndex}-{0}"]);
                pos.Add(_x2.MotionPosition["Arm右避让位"]);
                pos.Add(_r1.MotionPosition[$"点检矩阵Arm左{nozzleName}-{spotTrayIndex}-{0}"]);
                pos.Add(_ngAxis.MotionPosition[$"点检矩阵Arm左{nozzleName}"]);
                AxisMoveSimultaneously(new List<Axis>() { _x1, _x2, _r1, _ngAxis }, pos);
                //while(true)
                //{
                //    Thread.Sleep(20);
                //}
                if (!CheckFlowCondition()) return;
                SingleAxisMove2Point(_y1, $"点检矩阵Arm左{nozzleName}-{spotTrayIndex}-{0}");
                if (!CheckFlowCondition()) return;
                NozzlePutProductExt(_z1,
                                    new List<Cylinder>() { _recycleCylinders1[nozzleIndex] },
                                    new List<Cylinder>() { _recycleVacs1[nozzleIndex] },
                                    new List<Cylinder>() { _recycleRevVacs1[nozzleIndex] },
                                    null,
                                    $"点检矩阵Arm左{nozzleName}-{spotTrayIndex}-{0}",
                                    "待机位",
                                    zRelPos: SystemConfig.Instance.TestParam.ArmZHValuePutInNG,
                                    zRelSpeed: SystemConfig.Instance.TestParam.ArmZHValueSpeedPutInNG,
                                    5000,
                                    500);
                if (!CheckFlowCondition()) return;
                //交换料状态
                spotTray.Helper.SetCellStatus(spotTrayIndex, CellStatus.HasProduct);
                spotTray.Helper.SetCellBarcode(spotTrayIndex, feedTray.Helper.GetCell(nozzleIndex).SN);
                spotTray.Helper.SetCellResult(spotTrayIndex, feedTray.Helper.GetCell(nozzleIndex).Result);
                spotTray.Helper.SetCellTesters(spotTrayIndex, feedTray.Helper.GetCell(nozzleIndex).TestedTesters);

                feedTray.Helper.SetCellStatus(nozzleIndex, CellStatus.NoProduct);
                feedTray.Helper.SetCellBarcode(nozzleIndex, string.Empty);
                feedTray.Helper.SetCellResult(nozzleIndex, TestResult.NoTest);
            }
            else if (headerIndex == 1)
            {
                SingleAxisMove2Point(_y2, "旋转位");
                if (!CheckFlowCondition()) return;
                List<double> pos = new List<double>();
                pos.Add(_x2.MotionPosition[$"点检矩阵Arm右{nozzleName}-{spotTrayIndex}-{0}"]);
                pos.Add(_x1.MotionPosition["Arm左避让位"]);
                pos.Add(_r2.MotionPosition[$"点检矩阵Arm右{nozzleName}-{spotTrayIndex}-{0}"]);
                pos.Add(_ngAxis.MotionPosition[$"点检矩阵Arm右{nozzleName}"]);
                AxisMoveSimultaneously(new List<Axis>() { _x2, _x1, _r2, _ngAxis }, pos);
                if (!CheckFlowCondition()) return;
                SingleAxisMove2Point(_y2, $"点检矩阵Arm右{nozzleName}-{spotTrayIndex}-{0}");
                if (!CheckFlowCondition()) return;
                NozzlePutProductExt(_z2,
                                    new List<Cylinder>() { _recycleCylinders2[nozzleIndex] },
                                    new List<Cylinder>() { _recycleVacs2[nozzleIndex] },
                                    new List<Cylinder>() { _recycleRevVacs2[nozzleIndex] },
                                    null,
                                    $"点检矩阵Arm右{nozzleName}-{spotTrayIndex}-{0}",
                                    "待机位",
                                    zRelPos: SystemConfig.Instance.TestParam.ArmZHValuePutInNG,
                                    zRelSpeed: SystemConfig.Instance.TestParam.ArmZHValueSpeedPutInNG,
                                    5000,
                                    500);
                if (!CheckFlowCondition()) return;
                //交换料状态
                spotTray.Helper.SetCellStatus(spotTrayIndex, CellStatus.HasProduct);
                spotTray.Helper.SetCellBarcode(spotTrayIndex, feedTray.Helper.GetCell(nozzleIndex).SN);
                spotTray.Helper.SetCellResult(spotTrayIndex, feedTray.Helper.GetCell(nozzleIndex).Result);
                spotTray.Helper.SetCellTesters(spotTrayIndex, feedTray.Helper.GetCell(nozzleIndex).TestedTesters);

                feedTray.Helper.SetCellStatus(nozzleIndex, CellStatus.NoProduct);
                feedTray.Helper.SetCellBarcode(nozzleIndex, string.Empty);
                feedTray.Helper.SetCellResult(nozzleIndex, TestResult.NoTest);
            }
        }
        public void putANG(Tray ngTray, string trayName, string avoidPosName, int headerIndex, string nozzleName, int nozzleIndex, int testerIndex, Tray recycleTray)
        {
            AxisMoveSimultaneously(new List<Axis>() { _z1, _z2 }, "待机位");
            if (!CheckFlowCondition()) return;
            if (headerIndex == 0)
            {
                int columnIndex = testerIndex % 6;
                int putIndex = -1;
                for (int i = 0; i < 4; i++)
                {
                    if (ngTray.Helper.GetCell(i + columnIndex * 4).Status == CellStatus.NoProduct)
                    {
                        putIndex = i + columnIndex * 4;
                        break;
                    }
                }
                List<double> pos = new List<double>();
                pos.Add(_x1.MotionPosition[$"ANG矩阵Arm左{nozzleName}-{putIndex}-{0}"]);
                pos.Add(_x2.MotionPosition["Arm右避让位"]);
                pos.Add(_r1.MotionPosition[$"ANG矩阵Arm左{nozzleName}-{putIndex}-{0}"]);
                pos.Add(_ngAxis.MotionPosition[$"{nozzleName}ABB左"]);
                SingleAxisMove2Point(_y1, "旋转位");
                if (!CheckFlowCondition()) return;
                AxisMoveSimultaneously(new List<Axis>() { _x1, _x2, _r1, _ngAxis }, pos);
                if (!CheckFlowCondition()) return;
                SingleAxisMove2Point(_y1, $"ANG矩阵Arm左{nozzleName}-{putIndex}-{0}");
                if (!CheckFlowCondition()) return;
                NozzlePutProductExt(_z1,
                                    new List<Cylinder>() { _recycleCylinders1[nozzleIndex] },
                                    new List<Cylinder>() { _recycleVacs1[nozzleIndex] },
                                    new List<Cylinder>() { _recycleRevVacs1[nozzleIndex] },
                                    null,
                                    $"{trayName}{nozzleName}-{putIndex}-{0}",
                                    "待机位",
                                    zRelPos: SystemConfig.Instance.TestParam.ArmZHValuePutInNG,
                                    zRelSpeed: SystemConfig.Instance.TestParam.ArmZHValueSpeedPutInNG,
                                    5000,
                                    100);
                if (!CheckFlowCondition()) return;
                //交换料状态
                ngTray.Helper.SetCellStatus(putIndex, CellStatus.HasProduct);
                ngTray.Helper.SetCellBarcode(putIndex, recycleTray.Helper.GetCell(nozzleIndex).SN);
                ngTray.Helper.SetCellResult(putIndex, recycleTray.Helper.GetCell(nozzleIndex).Result);
                List<int> ss = recycleTray.Helper.GetCell(nozzleIndex).TestedTesters;
                ngTray.Helper.SetCellTesters(putIndex, recycleTray.Helper.GetCell(nozzleIndex).TestedTesters);

                recycleTray.Helper.SetCellStatus(nozzleIndex, CellStatus.NoProduct);
                recycleTray.Helper.SetCellBarcode(nozzleIndex, string.Empty);
                recycleTray.Helper.SetCellResult(nozzleIndex, TestResult.NoTest);
            }
            else if (headerIndex == 1)
            {
                int columnIndex = testerIndex % 6;
                int putIndex = -1;
                for (int i = 0; i < 4; i++)
                {
                    if (ngTray.Helper.GetCell(i + columnIndex * 4).Status == CellStatus.NoProduct)
                    {
                        putIndex = i + columnIndex * 4;
                        break;
                    }
                }
                List<double> pos = new List<double>();
                pos.Add(_x2.MotionPosition[$"ANG矩阵Arm右{nozzleName}-{putIndex}-{0}"]);
                pos.Add(_x1.MotionPosition["Arm左避让位"]);
                pos.Add(_r2.MotionPosition[$"ANG矩阵Arm右{nozzleName}-{putIndex}-{0}"]);
                pos.Add(_ngAxis.MotionPosition[$"{nozzleName}ABB右"]);
                //pos.Add(0);
                SingleAxisMove2Point(_y2, "旋转位");
                if (!CheckFlowCondition()) return;
                AxisMoveSimultaneously(new List<Axis>() { _x2, _x1, _r2, _ngAxis }, pos);
                if (!CheckFlowCondition()) return;
                SingleAxisMove2Point(_y2, $"ANG矩阵Arm右{nozzleName}-{putIndex}-{0}");
                if (!CheckFlowCondition()) return;
                NozzlePutProductExt(_z2,
                                    new List<Cylinder>() { _recycleCylinders2[nozzleIndex] },
                                    new List<Cylinder>() { _recycleVacs2[nozzleIndex] },
                                    new List<Cylinder>() { _recycleRevVacs2[nozzleIndex] },
                                    null,
                                    $"{trayName}{nozzleName}-{putIndex}-{0}",
                                    "待机位",
                                    zRelPos: SystemConfig.Instance.TestParam.ArmZHValuePutInNG,
                                    zRelSpeed: SystemConfig.Instance.TestParam.ArmZHValueSpeedPutInNG,
                                    5000,
                                    100);
                if (!CheckFlowCondition()) return;
                //交换料状态
                ngTray.Helper.SetCellStatus(putIndex, CellStatus.HasProduct);
                ngTray.Helper.SetCellBarcode(putIndex, recycleTray.Helper.GetCell(nozzleIndex).SN);
                ngTray.Helper.SetCellResult(putIndex, recycleTray.Helper.GetCell(nozzleIndex).Result);
                List<int> ss = recycleTray.Helper.GetCell(nozzleIndex).TestedTesters;
                ngTray.Helper.SetCellTesters(putIndex, recycleTray.Helper.GetCell(nozzleIndex).TestedTesters);

                recycleTray.Helper.SetCellStatus(nozzleIndex, CellStatus.NoProduct);
                recycleTray.Helper.SetCellBarcode(nozzleIndex, string.Empty);
                recycleTray.Helper.SetCellResult(nozzleIndex, TestResult.NoTest);
            }
        }
        public void getANG(Tray ngTray, string trayName, string avoidPosName, int headerIndex, string nozzleName, int nozzleIndex, int getIndex, Tray feedTray)
        {
            AxisMoveSimultaneously(new List<Axis>() { _z1, _z2 }, "待机位");
            if (!CheckFlowCondition()) return;
            if (headerIndex == 0)
            {
                List<double> pos = new List<double>();
                pos.Add(_x1.MotionPosition[$"ANG矩阵Arm左{nozzleName}-{getIndex}-{0}"]);
                pos.Add(_x2.MotionPosition["Arm右避让位"]);
                pos.Add(_r1.MotionPosition[$"ANG矩阵Arm左{nozzleName}-{getIndex}-{0}"]);
                pos.Add(_ngAxis.MotionPosition[$"{nozzleName}ABB左"]);
                SingleAxisMove2Point(_y1, "旋转位");
                if (!CheckFlowCondition()) return;
                AxisMoveSimultaneously(new List<Axis>() { _x1, _x2, _r1, _ngAxis }, pos);
                if (!CheckFlowCondition()) return;
                SingleAxisMove2Point(_y1, $"ANG矩阵Arm左{nozzleName}-{getIndex}-{0}");
                if (!CheckFlowCondition()) return;
                string localName = "前线ANG区";
                NozzleGetProductExt(_z1,
                                    new List<Cylinder>() { _feedCylinders1[nozzleIndex] },
                                    new List<Cylinder>() { _feedVacs1[nozzleIndex] },
                                    new List<Sensor>() { _feedVacSenses1[nozzleIndex] },
                                    null,
                                    null,
                                    $"{trayName}{nozzleName}-{getIndex}-{0}",
                                    "待机位",
                                    localName: $"{localName}:",
                                    5000,
                                    100,
                                    100,
                                    GlobalVariable.IsDryRun);
                if (!CheckFlowCondition()) return;
                //交换料状态
                feedTray.Helper.SetCellStatus(nozzleIndex, CellStatus.HasProduct);
                feedTray.Helper.SetCellBarcode(nozzleIndex, ngTray.Helper.GetCell(getIndex).SN);
                feedTray.Helper.SetCellResult(nozzleIndex, ngTray.Helper.GetCell(getIndex).Result);
                List<int> ss = ngTray.Helper.GetCell(getIndex).TestedTesters;
                feedTray.Helper.SetCellTesters(nozzleIndex, ngTray.Helper.GetCell(getIndex).TestedTesters);

                ngTray.Helper.SetCellStatus(getIndex, CellStatus.NoProduct);
                ngTray.Helper.SetCellBarcode(getIndex, string.Empty);
                ngTray.Helper.SetCellResult(getIndex, TestResult.NoTest);
            }
            else
            {
                List<double> pos = new List<double>();
                pos.Add(_x2.MotionPosition[$"ANG矩阵Arm右{nozzleName}-{getIndex}-{0}"]);
                pos.Add(_x1.MotionPosition["Arm左避让位"]);
                pos.Add(_r2.MotionPosition[$"ANG矩阵Arm右{nozzleName}-{getIndex}-{0}"]);
                pos.Add(_ngAxis.MotionPosition[$"{nozzleName}ABB右"]);
                //pos.Add(0);
                SingleAxisMove2Point(_y2, "旋转位");
                if (!CheckFlowCondition()) return;
                AxisMoveSimultaneously(new List<Axis>() { _x2, _x1, _r2, _ngAxis }, pos);
                if (!CheckFlowCondition()) return;
                SingleAxisMove2Point(_y2, $"ANG矩阵Arm右{nozzleName}-{getIndex}-{0}");
                if (!CheckFlowCondition()) return;
                string localName = "后线ANG区";
                NozzleGetProductExt(_z2,
                                    new List<Cylinder>() { _feedCylinders2[nozzleIndex] },
                                    new List<Cylinder>() { _feedVacs2[nozzleIndex] },
                                    new List<Sensor>() { _feedVacSenses2[nozzleIndex] },
                                    null,
                                    null,
                                    $"{trayName}{nozzleName}-{getIndex}-{0}",
                                    "待机位",
                                    localName: $"{localName}:",
                                    5000,
                                    100,
                                    100,
                                    GlobalVariable.IsDryRun);
                if (!CheckFlowCondition()) return;
                //交换料状态
                feedTray.Helper.SetCellStatus(nozzleIndex, CellStatus.HasProduct);
                feedTray.Helper.SetCellBarcode(nozzleIndex, ngTray.Helper.GetCell(getIndex).SN);
                feedTray.Helper.SetCellResult(nozzleIndex, ngTray.Helper.GetCell(getIndex).Result);
                List<int> ss = ngTray.Helper.GetCell(getIndex).TestedTesters;
                feedTray.Helper.SetCellTesters(nozzleIndex, ngTray.Helper.GetCell(getIndex).TestedTesters);

                ngTray.Helper.SetCellStatus(getIndex, CellStatus.NoProduct);
                ngTray.Helper.SetCellBarcode(getIndex, string.Empty);
                ngTray.Helper.SetCellResult(getIndex, TestResult.NoTest);
            }
        }
        //ABNG矩阵Arm左
        public void getABNG(Tray ngTray, string trayName, string avoidPosName, int headerIndex, string nozzleName, int nozzleIndex, int getIndex, Tray feedTray)
        {
            AxisMoveSimultaneously(new List<Axis>() { _z1, _z2 }, "待机位");
            if (!CheckFlowCondition()) return;
            if (headerIndex == 0)
            {
                List<double> pos = new List<double>();
                pos.Add(_x1.MotionPosition[$"ABNG矩阵Arm左{nozzleName}-{getIndex}-{0}"]);
                pos.Add(_x2.MotionPosition["Arm右避让位"]);
                pos.Add(_r1.MotionPosition[$"ABNG矩阵Arm左{nozzleName}-{getIndex}-{0}"]);
                pos.Add(_ngAxis.MotionPosition[$"{nozzleName}ABB左"]);
                SingleAxisMove2Point(_y1, "旋转位");
                if (!CheckFlowCondition()) return;
                AxisMoveSimultaneously(new List<Axis>() { _x1, _x2, _r1, _ngAxis }, pos);
                if (!CheckFlowCondition()) return;
                SingleAxisMove2Point(_y1, $"ABNG矩阵Arm左{nozzleName}-{getIndex}-{0}");
                if (!CheckFlowCondition()) return; 
                string localName = "前线ABNG区";
                NozzleGetProductExt(_z1,
                                    new List<Cylinder>() { _feedCylinders1[nozzleIndex] },
                                    new List<Cylinder>() { _feedVacs1[nozzleIndex] },
                                    new List<Sensor>() { _feedVacSenses1[nozzleIndex] },
                                    null,
                                    null,
                                    $"{trayName}{nozzleName}-{getIndex}-{0}",
                                    "待机位",
                                    localName: $"{localName}:",
                                    5000,
                                    100,
                                    100,
                                    GlobalVariable.IsDryRun);
                if (!CheckFlowCondition()) return;
                //交换料状态
                feedTray.Helper.SetCellStatus(nozzleIndex, CellStatus.HasProduct);
                feedTray.Helper.SetCellBarcode(nozzleIndex, ngTray.Helper.GetCell(getIndex).SN);
                feedTray.Helper.SetCellResult(nozzleIndex, ngTray.Helper.GetCell(getIndex).Result);
                List<int> ss = ngTray.Helper.GetCell(getIndex).TestedTesters;
                feedTray.Helper.SetCellTesters(nozzleIndex, ngTray.Helper.GetCell(getIndex).TestedTesters);

                ngTray.Helper.SetCellStatus(getIndex, CellStatus.NoProduct);
                ngTray.Helper.SetCellBarcode(getIndex, string.Empty);
                ngTray.Helper.SetCellResult(getIndex, TestResult.NoTest);
            }
            else
            {
                List<double> pos = new List<double>();
                pos.Add(_x2.MotionPosition[$"ABNG矩阵Arm右{nozzleName}-{getIndex}-{0}"]);
                pos.Add(_x1.MotionPosition["Arm左避让位"]);
                pos.Add(_r2.MotionPosition[$"ABNG矩阵Arm右{nozzleName}-{getIndex}-{0}"]);
                pos.Add(_ngAxis.MotionPosition[$"{nozzleName}ABB右"]);
                SingleAxisMove2Point(_y2, "旋转位");
                if (!CheckFlowCondition()) return;
                AxisMoveSimultaneously(new List<Axis>() { _x2, _x1, _r2, _ngAxis }, pos);
                if (!CheckFlowCondition()) return;
                SingleAxisMove2Point(_y2, $"ABNG矩阵Arm右{nozzleName}-{getIndex}-{0}");
                if (!CheckFlowCondition()) return;
                string localName = "后线ABNG区";
                NozzleGetProductExt(_z2,
                                    new List<Cylinder>() { _feedCylinders2[nozzleIndex] },
                                    new List<Cylinder>() { _feedVacs2[nozzleIndex] },
                                    new List<Sensor>() { _feedVacSenses2[nozzleIndex] },
                                    null,
                                    null,
                                    $"{trayName}{nozzleName}-{getIndex}-{0}",
                                    "待机位",
                                    localName: $"{localName}:",
                                    5000,
                                    100,
                                    100,
                                    GlobalVariable.IsDryRun);
                if (!CheckFlowCondition()) return;
                //交换料状态
                feedTray.Helper.SetCellStatus(nozzleIndex, CellStatus.HasProduct);
                feedTray.Helper.SetCellBarcode(nozzleIndex, ngTray.Helper.GetCell(getIndex).SN);
                feedTray.Helper.SetCellResult(nozzleIndex, ngTray.Helper.GetCell(getIndex).Result);
                List<int> ss = ngTray.Helper.GetCell(getIndex).TestedTesters;
                feedTray.Helper.SetCellTesters(nozzleIndex, ngTray.Helper.GetCell(getIndex).TestedTesters);

                ngTray.Helper.SetCellStatus(getIndex, CellStatus.NoProduct);
                ngTray.Helper.SetCellBarcode(getIndex, string.Empty);
                ngTray.Helper.SetCellResult(getIndex, TestResult.NoTest);
            }
        }
        public void getABNGClear(Tray ngTray, int headerIndex, int nozzleIndex, int getIndex, Tray feedTray)
        {
            AxisMoveSimultaneously(new List<Axis>() { _z1, _z2 }, "待机位");
            if (!CheckFlowCondition()) return;
            if (headerIndex == 0)
            {
                List<double> pos = new List<double>();
                pos.Add(_x1.MotionPosition[$"ABNG矩阵Arm左-{getIndex}-{nozzleIndex}"]);
                pos.Add(_x2.MotionPosition["Arm右避让位"]);
                pos.Add(_y1.MotionPosition[$"ABNG矩阵Arm左-{getIndex}-{nozzleIndex}"]);
                pos.Add(_r1.MotionPosition[$"ABNG矩阵Arm左-{getIndex}-{nozzleIndex}"]);
                AxisMoveSimultaneously(new List<Axis>() { _x1, _x2, _y1, _r1 }, pos);
                if (!CheckFlowCondition()) return;
                string localName = "前线ABNG区";
                NozzleGetProductExt(_z1,
                                    new List<Cylinder>() { _feedCylinders1[nozzleIndex] },
                                    new List<Cylinder>() { _feedVacs1[nozzleIndex] },
                                    new List<Sensor>() { _feedVacSenses1[nozzleIndex] },
                                    null,
                                    null,
                                    "Arm左放NG高度",
                                    "待机位",
                                    localName: $"{localName}:",
                                    5000,
                                    100,
                                    100,
                                    GlobalVariable.IsDryRun);
                if (!CheckFlowCondition()) return;
                //交换料状态
                feedTray.Helper.SetCellStatus(nozzleIndex, CellStatus.HasProduct);
                feedTray.Helper.SetCellBarcode(nozzleIndex, ngTray.Helper.GetCell(getIndex).SN);
                feedTray.Helper.SetCellResult(nozzleIndex, ngTray.Helper.GetCell(getIndex).Result);
                feedTray.Helper.SetCellTesters(nozzleIndex, ngTray.Helper.GetCell(getIndex).TestedTesters);

                ngTray.Helper.SetCellStatus(getIndex, CellStatus.NoProduct);
                ngTray.Helper.SetCellBarcode(getIndex, string.Empty);
                ngTray.Helper.SetCellResult(getIndex, TestResult.NoTest);
            }
            else
            {
                List<double> pos = new List<double>();
                pos.Add(_x2.MotionPosition[$"ABNG矩阵Arm右-{getIndex}-{nozzleIndex}"]);
                pos.Add(_x1.MotionPosition["Arm左避让位"]);
                pos.Add(_y2.MotionPosition[$"ABNG矩阵Arm右-{getIndex}-{nozzleIndex}"]);
                pos.Add(_r2.MotionPosition[$"ABNG矩阵Arm右-{getIndex}-{nozzleIndex}"]);
                AxisMoveSimultaneously(new List<Axis>() { _x2, _x1, _y2, _r2 }, pos);
                if (!CheckFlowCondition()) return;
                string localName = "后线ABNG区";
                NozzleGetProductExt(_z2,
                                    new List<Cylinder>() { _feedCylinders2[nozzleIndex] },
                                    new List<Cylinder>() { _feedVacs2[nozzleIndex] },
                                    new List<Sensor>() { _feedVacSenses2[nozzleIndex] },
                                    null,
                                    null,
                                    "Arm右放NG高度",
                                    "待机位",
                                    localName: $"{localName}:",
                                    5000,
                                    100,
                                    100,
                                    GlobalVariable.IsDryRun);
                if (!CheckFlowCondition()) return;
                //交换料状态
                feedTray.Helper.SetCellStatus(nozzleIndex, CellStatus.HasProduct);
                feedTray.Helper.SetCellBarcode(nozzleIndex, ngTray.Helper.GetCell(getIndex).SN);
                feedTray.Helper.SetCellResult(nozzleIndex, ngTray.Helper.GetCell(getIndex).Result);
                feedTray.Helper.SetCellTesters(nozzleIndex, ngTray.Helper.GetCell(getIndex).TestedTesters);

                ngTray.Helper.SetCellStatus(getIndex, CellStatus.NoProduct);
                ngTray.Helper.SetCellBarcode(getIndex, string.Empty);
                ngTray.Helper.SetCellResult(getIndex, TestResult.NoTest);
            }
        }
        public void putABNG(Tray ngTray, string trayName, string avoidPosName, int headerIndex, string nozzleName, int nozzleIndex, int testerIndex, Tray recycleTray)
        {
            AxisMoveSimultaneously(new List<Axis>() { _z1, _z2 }, "待机位");
            if (!CheckFlowCondition()) return;
            if (headerIndex == 0)
            {
                int columnIndex = testerIndex % 6;
                int putIndex = -1;
                for (int i = 0; i < 4; i++)
                {
                    if (ngTray.Helper.GetCell(i + columnIndex * 4).Status == CellStatus.NoProduct)
                    {
                        putIndex = i + columnIndex * 4;
                        break;
                    }
                }
                List<double> pos = new List<double>();
                pos.Add(_x1.MotionPosition[$"ABNG矩阵Arm左{nozzleName}-{putIndex}-{0}"]);
                pos.Add(_x2.MotionPosition["Arm右避让位"]);
                pos.Add(_r1.MotionPosition[$"ABNG矩阵Arm左{nozzleName}-{putIndex}-{0}"]);
                pos.Add(_ngAxis.MotionPosition[$"{nozzleName}ABB左"]);
                SingleAxisMove2Point(_y1, "旋转位");
                if (!CheckFlowCondition()) return;
                AxisMoveSimultaneously(new List<Axis>() { _x1, _x2, _r1, _ngAxis }, pos);
                if (!CheckFlowCondition()) return;
                SingleAxisMove2Point(_y1, $"ABNG矩阵Arm左{nozzleName}-{putIndex}-{0}");
                if (!CheckFlowCondition()) return;
                NozzlePutProductExt(_z1,
                                    new List<Cylinder>() { _recycleCylinders1[nozzleIndex] },
                                    new List<Cylinder>() { _recycleVacs1[nozzleIndex] },
                                    new List<Cylinder>() { _recycleRevVacs1[nozzleIndex] },
                                    null,
                                    $"{trayName}{nozzleName}-{putIndex}-{0}",
                                    "待机位",
                                    zRelPos: SystemConfig.Instance.TestParam.ArmZHValuePutInNG,
                                    zRelSpeed: SystemConfig.Instance.TestParam.ArmZHValueSpeedPutInNG,
                                    5000,
                                    100);
                if (!CheckFlowCondition()) return;
                //交换料状态
                ngTray.Helper.SetCellStatus(putIndex, CellStatus.HasProduct);
                ngTray.Helper.SetCellBarcode(putIndex, recycleTray.Helper.GetCell(nozzleIndex).SN);
                ngTray.Helper.SetCellResult(putIndex, recycleTray.Helper.GetCell(nozzleIndex).Result);
                List<int> ss = recycleTray.Helper.GetCell(nozzleIndex).TestedTesters;
                ngTray.Helper.SetCellTesters(putIndex, recycleTray.Helper.GetCell(nozzleIndex).TestedTesters);

                recycleTray.Helper.SetCellStatus(nozzleIndex, CellStatus.NoProduct);
                recycleTray.Helper.SetCellBarcode(nozzleIndex, string.Empty);
                recycleTray.Helper.SetCellResult(nozzleIndex, TestResult.NoTest);
            }
            else if (headerIndex == 1)
            {
                int columnIndex = testerIndex % 6;
                int putIndex = -1;
                for (int i = 0; i < 4; i++)
                {
                    if (ngTray.Helper.GetCell(i + columnIndex * 4).Status == CellStatus.NoProduct)
                    {
                        putIndex = i + columnIndex * 4;
                        break;
                    }
                }
                List<double> pos = new List<double>();
                pos.Add(_x2.MotionPosition[$"ABNG矩阵Arm右{nozzleName}-{putIndex}-{0}"]);
                pos.Add(_x1.MotionPosition["Arm左避让位"]);
                pos.Add(_r2.MotionPosition[$"ABNG矩阵Arm右{nozzleName}-{putIndex}-{0}"]);
                pos.Add(_ngAxis.MotionPosition[$"{nozzleName}ABB右"]);
                SingleAxisMove2Point(_y2, "旋转位");
                if (!CheckFlowCondition()) return;
                AxisMoveSimultaneously(new List<Axis>() { _x2, _x1, _r2, _ngAxis }, pos);
                if (!CheckFlowCondition()) return;
                SingleAxisMove2Point(_y2, $"ABNG矩阵Arm右{nozzleName}-{putIndex}-{0}");
                if (!CheckFlowCondition()) return;
                NozzlePutProductExt(_z2,
                                    new List<Cylinder>() { _recycleCylinders2[nozzleIndex] },
                                    new List<Cylinder>() { _recycleVacs2[nozzleIndex] },
                                    new List<Cylinder>() { _recycleRevVacs2[nozzleIndex] },
                                    null,
                                    $"{trayName}{nozzleName}-{putIndex}-{0}",
                                    "待机位",
                                    zRelPos: SystemConfig.Instance.TestParam.ArmZHValuePutInNG,
                                    zRelSpeed: SystemConfig.Instance.TestParam.ArmZHValueSpeedPutInNG,
                                    5000,
                                    100);
                if (!CheckFlowCondition()) return;
                //交换料状态
                ngTray.Helper.SetCellStatus(putIndex, CellStatus.HasProduct);
                ngTray.Helper.SetCellBarcode(putIndex, recycleTray.Helper.GetCell(nozzleIndex).SN);
                ngTray.Helper.SetCellResult(putIndex, recycleTray.Helper.GetCell(nozzleIndex).Result);
                List<int> ss = recycleTray.Helper.GetCell(nozzleIndex).TestedTesters;
                ngTray.Helper.SetCellTesters(putIndex, recycleTray.Helper.GetCell(nozzleIndex).TestedTesters);

                recycleTray.Helper.SetCellStatus(nozzleIndex, CellStatus.NoProduct);
                recycleTray.Helper.SetCellBarcode(nozzleIndex, string.Empty);
                recycleTray.Helper.SetCellResult(nozzleIndex, TestResult.NoTest);
            }
        }
        public void PutBuffer(Tray bufferTray, string putBufferTrayName, Tray bufferTrayUI, int headerIndex, string nozzleName, int nozzleIndex, Tray headerTray)
        {
            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"緩存區放料:{bufferTray.Name}，{putBufferTrayName}，headerIndex:{headerIndex},nozzleName:{nozzleName},nozzleIndex:{nozzleIndex}", this.Description, 0, ""));
            AxisMoveSimultaneously(new List<Axis>() { _z1, _z2 }, "待机位");
            if (!CheckFlowCondition()) return;
            if (headerIndex == 0)
            {
                int putIndex = bufferTray.Helper.GetFirstIndex(CellStatus.NoProduct);
                List<double> pos = new List<double>();
                MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"緩存區放料:{putBufferTrayName}{nozzleName}-{putIndex}-{0}", this.Description, 0, ""));
                pos.Add(_x1.MotionPosition[$"{putBufferTrayName}{nozzleName}-{putIndex}-{0}"]);
                pos.Add(_x2.MotionPosition["Arm右避让位"]);
                pos.Add(_r1.MotionPosition[$"{putBufferTrayName}{nozzleName}-{putIndex}-{0}"]);
                pos.Add(_ngAxis.MotionPosition[$"{nozzleName}缓存左"]);
                SingleAxisMove2Point(_y1, "旋转位");
                if (!CheckFlowCondition()) return;
                AxisMoveSimultaneously(new List<Axis>() { _x1, _x2, _r1, _ngAxis }, pos);
                if (!CheckFlowCondition()) return;
                SingleAxisMove2Point(_y1, $"{putBufferTrayName}{nozzleName}-{putIndex}-{0}");
                if (!CheckFlowCondition()) return;
                NozzlePutProductExt(_z1,
                                    new List<Cylinder>() { _recycleCylinders1[nozzleIndex] },
                                    new List<Cylinder>() { _recycleVacs1[nozzleIndex] },
                                    new List<Cylinder>() { _recycleRevVacs1[nozzleIndex] },
                                    null,
                                    $"{putBufferTrayName}{nozzleName}-{putIndex}-{0}",
                                    "待机位",
                                    zRelPos: SystemConfig.Instance.TestParam.ArmZHValuePutInNG,
                                    zRelSpeed: SystemConfig.Instance.TestParam.ArmZHValueSpeedPutInNG,
                                    5000,
                                    800);
                if (!CheckFlowCondition()) return;
                //交换料状态
                bufferTray.Helper.SetCellStatus(putIndex, CellStatus.HasProduct);
                bufferTray.Helper.SetCellBarcode(putIndex, headerTray.Helper.GetCell(nozzleIndex).SN);
                bufferTray.Helper.SetCellResult(putIndex, headerTray.Helper.GetCell(nozzleIndex).Result);
                bufferTrayUI.Helper.SetCellStatus(putIndex, CellStatus.HasProduct);
                bufferTrayUI.Helper.SetCellBarcode(putIndex, headerTray.Helper.GetCell(nozzleIndex).SN);
                bufferTrayUI.Helper.SetCellResult(putIndex, headerTray.Helper.GetCell(nozzleIndex).Result);
                headerTray.Helper.SetCellStatus(nozzleIndex, CellStatus.NoProduct);
                headerTray.Helper.SetCellBarcode(nozzleIndex, string.Empty);
                headerTray.Helper.SetCellResult(nozzleIndex, TestResult.NoTest);
            }
            else if (headerIndex == 1)
            {
                int putIndex = bufferTray.Helper.GetFirstIndex(CellStatus.NoProduct);
                List<double> pos = new List<double>();
                string keyStr = $"{putBufferTrayName}{nozzleName}-{putIndex}-{0}";
                MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"緩存區放料:{keyStr}", this.Description, 0, ""));
                while (!_x2.MotionPosition.Keys.Contains(keyStr))
                {
                    ShowWarnAndPause($"{_x2.Description}中不存在点位{keyStr},异常情况！", "系统");
                    if (!CheckFlowCondition()) return;
                }
                if (!CheckFlowCondition()) return;
                pos.Add(_x2.MotionPosition[keyStr]);
                //double pos11111 = _x1.MotionPosition["缓存矩阵吸嘴4"];
                pos.Add(_x1.MotionPosition["Arm左避让位"]);
                pos.Add(_r2.MotionPosition[$"{putBufferTrayName}{nozzleName}-{putIndex}-{0}"]);
                pos.Add(_ngAxis.MotionPosition[$"{nozzleName}缓存右"]);
                SingleAxisMove2Point(_y2, "旋转位");
                if (!CheckFlowCondition()) return;
                AxisMoveSimultaneously(new List<Axis>() { _x2, _x1, _r2, _ngAxis }, pos);
                if (!CheckFlowCondition()) return;
                SingleAxisMove2Point(_y2, $"{putBufferTrayName}{nozzleName}-{putIndex}-{0}");
                if (!CheckFlowCondition()) return;
                NozzlePutProductExt(_z2,
                                    new List<Cylinder>() { _recycleCylinders2[nozzleIndex] },
                                    new List<Cylinder>() { _recycleVacs2[nozzleIndex] },
                                    new List<Cylinder>() { _recycleRevVacs2[nozzleIndex] },
                                    null,
                                    $"{putBufferTrayName}{nozzleName}-{putIndex}-{0}",
                                    "待机位",
                                    zRelPos: SystemConfig.Instance.TestParam.ArmZHValuePutInNG,
                                    zRelSpeed: SystemConfig.Instance.TestParam.ArmZHValueSpeedPutInNG,
                                    5000,
                                    800);
                if (!CheckFlowCondition()) return;
                //交换料状态
                bufferTray.Helper.SetCellStatus(putIndex, CellStatus.HasProduct);
                bufferTray.Helper.SetCellBarcode(putIndex, headerTray.Helper.GetCell(nozzleIndex).SN);
                bufferTray.Helper.SetCellResult(putIndex, headerTray.Helper.GetCell(nozzleIndex).Result);
                bufferTrayUI.Helper.SetCellStatus(putIndex, CellStatus.HasProduct);
                bufferTrayUI.Helper.SetCellBarcode(putIndex, headerTray.Helper.GetCell(nozzleIndex).SN);
                bufferTrayUI.Helper.SetCellResult(putIndex, headerTray.Helper.GetCell(nozzleIndex).Result);
                headerTray.Helper.SetCellStatus(nozzleIndex, CellStatus.NoProduct);
                headerTray.Helper.SetCellBarcode(nozzleIndex, string.Empty);
                headerTray.Helper.SetCellResult(nozzleIndex, TestResult.NoTest);
            }
        }
        public void GetBuffer(Tray bufferTray, string getBufferTrayName, Tray bufferTrayUI, int headerIndex, string nozzleName, int nozzleIndex, Tray headerTray)
        {
            AxisMoveSimultaneously(new List<Axis>() { _z1, _z2 }, "待机位");
            if (!CheckFlowCondition()) return;
            if (headerIndex == 0)
            {
                int getIndex = bufferTray.Helper.GetFirstIndex(CellStatus.HasProduct);
                List<double> pos = new List<double>();
                pos.Add(_x1.MotionPosition[$"{getBufferTrayName}{nozzleName}-{getIndex}-{0}"]);
                pos.Add(_x2.MotionPosition["Arm右避让位"]);
                pos.Add(_r1.MotionPosition[$"{getBufferTrayName}{nozzleName}-{getIndex}-{0}"]);
                pos.Add(_ngAxis.MotionPosition[$"{nozzleName}缓存左"]);
                SingleAxisMove2Point(_y1, "旋转位");
                if (!CheckFlowCondition()) return;
                AxisMoveSimultaneously(new List<Axis>() { _x1, _x2, _r1, _ngAxis }, pos);
                if (!CheckFlowCondition()) return;
                SingleAxisMove2Point(_y1, $"{getBufferTrayName}{nozzleName}-{getIndex}-{0}");
                if (!CheckFlowCondition()) return;
                string localName = "前线缓存区";
                NozzleGetProductExt(_z1,
                                    new List<Cylinder>() { _recycleCylinders1[nozzleIndex] },
                                    new List<Cylinder>() { _recycleVacs1[nozzleIndex] },
                                    new List<Sensor>() { _recycleVacSenses1[nozzleIndex] },
                                    null,
                                    null,
                                    $"{getBufferTrayName}{nozzleName}-{getIndex}-{0}",
                                    "待机位",
                                    localName: $"{localName}:",
                                    5000,
                                    800,
                                    50,
                                    GlobalVariable.IsDryRun);
                if (!CheckFlowCondition()) return;
                //交换料状态
                headerTray.Helper.SetCellStatus(nozzleIndex, CellStatus.HasProduct);
                headerTray.Helper.SetCellBarcode(nozzleIndex, bufferTray.Helper.GetCell(getIndex).SN);
                headerTray.Helper.SetCellResult(nozzleIndex, bufferTray.Helper.GetCell(getIndex).Result);
                bufferTray.Helper.SetCellStatus(getIndex, CellStatus.NoProduct);
                bufferTray.Helper.SetCellBarcode(getIndex, string.Empty);
                bufferTray.Helper.SetCellResult(getIndex, TestResult.NoTest);
                bufferTrayUI.Helper.SetCellStatus(getIndex, CellStatus.NoProduct);
                bufferTrayUI.Helper.SetCellBarcode(getIndex, string.Empty);
                bufferTrayUI.Helper.SetCellResult(getIndex, TestResult.NoTest);
            }
            else if (headerIndex == 1)
            {
                int getIndex = bufferTray.Helper.GetFirstIndex(CellStatus.HasProduct);
                List<double> pos = new List<double>();
                pos.Add(_x2.MotionPosition[$"{getBufferTrayName}{nozzleName}-{getIndex}-{0}"]);
                pos.Add(_x1.MotionPosition["Arm左避让位"]);
                pos.Add(_r2.MotionPosition[$"{getBufferTrayName}{nozzleName}-{getIndex}-{0}"]);
                pos.Add(_ngAxis.MotionPosition[$"{nozzleName}缓存右"]);
                SingleAxisMove2Point(_y2, "旋转位");
                if (!CheckFlowCondition()) return;
                AxisMoveSimultaneously(new List<Axis>() { _x2, _x1, _r2, _ngAxis }, pos);
                if (!CheckFlowCondition()) return;
                SingleAxisMove2Point(_y2, $"{getBufferTrayName}{nozzleName}-{getIndex}-{0}");
                if (!CheckFlowCondition()) return;
                string localName = "后线缓存区";
                NozzleGetProductExt(_z2,
                                    new List<Cylinder>() { _recycleCylinders2[nozzleIndex] },
                                    new List<Cylinder>() { _recycleVacs2[nozzleIndex] },
                                    new List<Sensor>() { _recycleVacSenses2[nozzleIndex] },
                                    null,
                                    null,
                                    $"{getBufferTrayName}{nozzleName}-{getIndex}-{0}",
                                    "待机位",
                                    localName: $"{localName}:",
                                    5000,
                                    800,
                                    500,
                                    GlobalVariable.IsDryRun);
                if (!CheckFlowCondition()) return;
                //交换料状态
                headerTray.Helper.SetCellStatus(nozzleIndex, CellStatus.HasProduct);
                headerTray.Helper.SetCellBarcode(nozzleIndex, bufferTray.Helper.GetCell(getIndex).SN);
                headerTray.Helper.SetCellResult(nozzleIndex, bufferTray.Helper.GetCell(getIndex).Result);
                bufferTray.Helper.SetCellStatus(getIndex, CellStatus.NoProduct);
                bufferTray.Helper.SetCellBarcode(getIndex, string.Empty);
                bufferTray.Helper.SetCellResult(getIndex, TestResult.NoTest);
                bufferTrayUI.Helper.SetCellStatus(getIndex, CellStatus.NoProduct);
                bufferTrayUI.Helper.SetCellBarcode(getIndex, string.Empty);
                bufferTrayUI.Helper.SetCellResult(getIndex, TestResult.NoTest);
            }
        }
        /// <summary>
        /// /// 有足够的ANG的料去复测的逻辑
        /// 1. 123或456中的料，1穴和2穴的加起来够2颗
        /// 2、 123或456中的料，同一个tester的满了2颗，需要取走1颗去测
        /// </summary>
        /// <param name="isClear"></param>
        /// <param name="testerIndex"></param>
        /// <param name="fromANGTray1"></param>
        /// <returns></returns>
        public bool LeftHasEnoughANG2Retest(bool isClear, out (int, int) testerIndex)
        {
            //前12个
            List<Cell> cells123 = new List<Cell>();
            for (int i = 0; i < 12; i++)
            {
                cells123.Add(_aNGTray.Helper.GetCell(i));
            }
            List<int> ang123 = cells123.Select((c, index) => new { cell = c, Index = index })
                                       .Where(item => item.cell.Status == CellStatus.HasProduct)
                                       .Select(item => item.Index).ToList();
            if (isClear)
            {
                if (ang123.Count >= 1)
                {
                    testerIndex = (ang123[0], ang123[0]);
                    return true;
                }
            }
            else
            {
                //遍历前面123治具的ANG
                //先凑2个
                //拿前面12个
                if (ang123.Count >= 2)
                {
                    testerIndex = (ang123[0], ang123[1]);
                    return true;
                }
            }
            testerIndex = (-1, -1);
            return false;
        }
        public bool RightHasEnoughANG2Retest(bool isClear, out (int, int) testerIndex)
        {
            List<Cell> cells456 = new List<Cell>();
            for (int i = 12; i < 24; i++)
            {
                cells456.Add(_aNGTray.Helper.GetCell(i));
            }
            List<int> ang456 = cells456.Select((c, index) => new { cell = c, Index = index })
                                       .Where(item => item.cell.Status == CellStatus.HasProduct)
                                       .Select(item => item.Index).ToList();
            if (isClear)
            {
                if (ang456.Count >= 1)
                {
                    testerIndex = (ang456[0] + 12, ang456[0] + 12);
                    return true;
                }
            }
            else
            {
                ///遍历后面456治具的ANG
                //先凑2个
                //拿后面的12个
                if (ang456.Count >= 2)
                {
                    testerIndex = (ang456[0] + 12, ang456[1] + 12);
                    return true;
                }
            }
            testerIndex = (-1, -1);
            return false;
        }
        public bool LeftHasEnoughABNG2Retest(bool isClear, out (int, int) cellIndex)
        {
            if (isClear)
            {
                for (int i = 0; i < 12; i++)
                {
                    if (_abNGTray.Helper.GetCell(i).Status == CellStatus.HasProduct)
                    {
                        cellIndex = (i, i);
                        return true;
                    }
                }
                cellIndex = (-1, -1);
                return false;
            }
            else
            {
                for (int i = 0; i < 3; i++)
                {
                    List<Cell> cells123 = new List<Cell>();
                    for (int j = 0; j < 4; j++)
                    {
                        cells123.Add(_abNGTray.Helper.GetCell(i * 4 + j));
                    }
                    List<int> ang123 = cells123.Select((c, index) => new { cell = c, Index = index })
                                               .Where(item => item.cell.Status == CellStatus.HasProduct)
                                               .Select(item => item.Index).ToList();
                    if (ang123.Count >= 2)
                    {
                        cellIndex = (i * 4 + ang123[0], i * 4 + ang123[1]);
                        return true;
                    }
                }
                cellIndex = (-1, -1);
                return false;
            }
        }
        public bool RightHasEnoughABNG2Retest(bool isClear, out (int, int) cellIndex)
        {
            if (isClear)
            {
                for (int i = 12; i < 24; i++)
                {
                    if (_abNGTray.Helper.GetCell(i).Status == CellStatus.HasProduct)
                    {
                        cellIndex = (i, i);
                        return true;
                    }
                }
                cellIndex = (-1, -1);
                return false;
            }
            else
            {
                for (int i = 3; i < 6; i++)
                {
                    List<Cell> cells456 = new List<Cell>();
                    for (int j = 0; j < 4; j++)
                    {
                        cells456.Add(_abNGTray.Helper.GetCell(i * 4 + j));
                    }
                    List<int> ang456 = cells456.Select((c, index) => new { cell = c, Index = index })
                                                .Where(item => item.cell.Status == CellStatus.HasProduct)
                                                .Select(item => item.Index).ToList();
                    if (ang456.Count >= 2)
                    {
                        cellIndex = (i * 4 + ang456[0], i * 4 + ang456[1]);
                        return true;
                    }
                }
                cellIndex = (-1, -1);
                return false;
            }
        }
        public void safetyCheck(bool upReady)
        {
            string moduleName = _isFront ? "前Arm模组" : "后Arm模组";
            if (!isSimulate)
            {
                while (!_ngInOrigin.WaitOn())
                {
                    ShowWarnAndPause("NG料层不在安全位置", moduleName);
                    Thread.Sleep(20);
                }
                //while (_ngInMove.WaitOn())
                //{
                //    ShowWarnAndPause("NG料层不在安全位置", moduleName);
                //    Thread.Sleep(20);
                //}
                if (!upReady)
                {
                    while (!_upInMove.WaitOn())
                    {
                        ShowWarnAndPause("精定位上层不在安全位置", moduleName);
                        Thread.Sleep(20);
                    }
                    while (_upInOrigin.WaitOn())
                    {
                        ShowWarnAndPause("精定位上层不在安全位置", moduleName);
                        Thread.Sleep(20);
                    }
                }
            }
        }
        public void WaitTesterFinish(int testerIndex)
        {
            int moduleIndex = _isFront ? 0 + testerIndex / 3 : 2 + testerIndex / 3;
            int tester = testerIndex % 3;
            TesterStatus status = (_flowManager.SelectFlow($"测试模组{moduleIndex + 1}{tester + 1}") as TesterLogic).CurrentTesterStatus;
            while (status != TesterStatus.TestFinish && !IsBreak())
            {
                status = (_flowManager.SelectFlow($"测试模组{moduleIndex + 1}{tester + 1}") as TesterLogic).CurrentTesterStatus;
                Thread.Sleep(20);
            }
            if (!CheckFlowCondition()) return;
        }
        public Tray GetANGTray()
        {
            return _aNGTray;
        }
        public Tray GetABNGTray()
        {
            return _abNGTray;
        }
        public Tray GetABBNGTray()
        {
            return _abbNGTray;
        }
        public Tray GetBufferTray1()
        {
            return _bufferTray1;
        }
        public Tray GetBufferTray2()
        {
            return _bufferTray2;
        }
        public Tray GetSpotCheckTray()
        {
            return _spotCheckTray;
        }
    }
}
